Hibernate的本机查询和缓存机制

Bea*_*ast 9 java orm caching hibernate jpa

我有一个关于Hibernate缓存机制的问题.我在文章中读到了hibernate中本机SQLquery的执行,使缓存的所有区域无效,因为hibernate对它将影响哪个特定实体一无所知.这里缓存的所有区域意味着我们在谈论二级缓存的各个区域或两级缓存(第一级缓存,二级缓存)还是仅二级缓存或仅第一级缓存?

Vla*_*cea 23

文章介绍了Hibernate的查询缓存是如何工作的,并在现有的缓存条目原生查询的效果.

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

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

这样它就知道哪些查询缓存无效,否则它可能会丢弃所有内容:

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 );
    }
}
Run Code Online (Sandbox Code Playgroud)

因此,正如您所看到的,该区域的整个数据被逐出.

这仅影响二级缓存.每次运行本机查询时都不会清除第一级缓存(即会话),因为这会分离所有当前的"附加实体",从而在实体状态期望中产生意外后果.但是在每个查询(HQL或本机)之前刷新会话以使db和会话在执行查询之前保持同步,因此在发出新的select之前,第一级缓存是一致的.

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

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