当前位置: 首页 > 面试题库 >

Hibernate的本机查询和缓存机制

公羊招
2023-03-14
问题内容

我有一个关于Hibernate缓存机制的问题。我在文章中已经读到,在hibernate中执行本机SQLquery会使缓存的所有区域无效,因为hibernate不知道它将影响哪个特定实体。在这里,缓存的所有区域都是在讨论二级缓存或二级缓存(一级缓存,二级缓存)或仅二级缓存或仅一级缓存的各个区域吗?


问题答案:

该文章介绍了Hibernate的查询缓存是如何工作的,并原生查询的在现有的高速缓存条目的影响。

使用SQLQuery,Hibernate无法知道您可能会影响哪些缓存区域,但是幸运的是,您可以明确地指示它:

SQLQuery sqlQuery = session.createSQLQuery(
    "UPDATE CUSTOMER SET ... WHERE ..."); 
sqlQuery.addSynchronizedEntityClass(Person.class); int
int updateCount = sqlQuery.executeUpdate();

通过这种方式,它知道哪些查询缓存无效,否则它可能会丢弃所有内容:

private static class EntityCleanup {
    private final EntityRegionAccessStrategy cacheAccess;
    private final SoftLock cacheLock;

    private EntityCleanup(EntityRegionAccessStrategy cacheAccess) {
        this.cacheAccess = cacheAccess;
        this.cacheLock = cacheAccess.lockRegion();
        cacheAccess.removeAll();
    }

    private void release() {
        cacheAccess.unlockRegion( cacheLock );
    }
}

private static class CollectionCleanup {
    private final CollectionRegionAccessStrategy cacheAccess;
    private final SoftLock cacheLock;

    private CollectionCleanup(CollectionRegionAccessStrategy cacheAccess) {
        this.cacheAccess = cacheAccess;
        this.cacheLock = cacheAccess.lockRegion();
        cacheAccess.removeAll();
    }

    private void release() {
        cacheAccess.unlockRegion( cacheLock );
    }
}

private class NaturalIdCleanup {
    private final NaturalIdRegionAccessStrategy naturalIdCacheAccessStrategy;
    private final SoftLock cacheLock;

    public NaturalIdCleanup(NaturalIdRegionAccessStrategy naturalIdCacheAccessStrategy) {
        this.naturalIdCacheAccessStrategy = naturalIdCacheAccessStrategy;
        this.cacheLock = naturalIdCacheAccessStrategy.lockRegion();
        naturalIdCacheAccessStrategy.removeAll();
    }

    private void release() {
        naturalIdCacheAccessStrategy.unlockRegion( cacheLock );
    }
}

因此,如您所见,该区域的所有数据都被驱逐了。

这仅影响二级缓存。每次运行本机查询时,都不会清除第一级缓存(也称为会话),因为这会分离当前的所有“附加实体”,从而给实体状态期望带来意外的后果。但是在每个查询(HQL或本机查询)之前,都会刷新会话,以便在执行查询之前数据库和会话处于同步状态,因此在发出新选择之前,一级缓存是一致的。

整个区域将失效,而不是整个二级缓存失效。实体定义了一个缓存区域,因此更新特定实体表只会删除属于该特定表的所有实体,这些实体受本机查询的影响。

但是,覆盖与本机查询关联的查询空间定义是一种自定义Hibernate的方式,该方式不像使用默认实现那样清除缓存区域。



 类似资料:
  • 问题内容: JPA()中的本机查询是否支持缓存? 我正在填写自己的数据传输对象,因为sql查询会联接多个表,并且仅从表中获取几个列。 问候 问题答案: 这是可能的,但 您必须使用显式或。 也可以看看 缓存SQL查询问题 hibernate:真正了解二级和查询缓存

  • 我想在我的repo中写一个本机查询“Select*in from table”。表名与实体名不同。 运行查询时, 1如果我把实体名称返回表未找到。 2如果我将表名放在查询中,则查询的验证失败。 问题是 如果我使用"Select*from TariffPacks r2..., nativeQuery=true",我得到错误TariffPacks不存在。如果我使用"Select*from RECHAR

  • 我得到错误 我有JPA Hibernate配置和使用Eh缓存的查询缓存和二级缓存。 配置:PostgreSQL 9.6 JPA 2.1 Hibernate 5.2.3。最终的 我正在尝试使用SqlResultSetMapping[自定义结果集类]执行NativeQuery。当我禁用缓存时,一切正常。 但是,在启用缓存时出现上述错误。除了NativeQuery,缓存工作正常。 表架构: SQL本机查

  • 问题内容: 我在Oracle中有一个表,其中SC_CUR_CODE列为CHAR(3) 当我做: 我看到了,而不是和 是一个java.lang.Character 我怎样才能得到充分的价值和? 问题答案: 似乎Hibernate读取类型为的值。尝试将其转换为: 通过接口使用Hibernate时,您可以改为设置一个结果类型(也可以通过JPA 2.0 访问): 从HHH-2220开始,Hibernate

  • 当使用jpa本机查询 事务传播是我们正在使用的正确jpa的唯一特性吗? 在我的意见中,我就像使用普通的旧jdbc pluc jpa事务传播 我正在阅读PRO JPA一书,根据我的理解 当我们使用JPA本机查询获取一组标量值时(与我们使用jdbc的方式很相似),实际上没有托管实体和持久性上下文的概念。当我们通过本机查询检索实体时,情况会发生变化。

  • 我需要通过在Hibernate中执行本机查询获得结果集。虽然我使用的是EntityManager,但查询和结果集可能不是实体。 当我尝试下面的代码时,我得到了一个结果。因为我要求的是一个有值的结果。(Hibernate JPA) 结果是:爱丽丝 当我试图从相同的代码中获得多个select out(查询为select name)时,指定来自fresher_test(其中id=1) 这有一种方法,我可