Hibernate的原生查询和缓存机制

Hibernate的原生查询和缓存机制

本文介绍了Hibernate的原生查询和缓存机制的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a question regarding Hibernate caching mechanism.I have read in the articles that native SQLquery execution in hibernate, invalidates all regions of cache because hibernate does not have any idea regarding which particular entity it is going to affect. Here all regions of cache means are we talking about various regions of the second level cache or both levels of cache(first level cache,second level cache) or only second level cache or only first level cache?

推荐答案

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

Using SQLQuery, Hibernate couldn't know what cache regions you might affect, but luckily you can explicitly instruct it:

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

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

This way it knows what query caches to invalidate, otherwise it may discard everything:

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 );
    }
}

因此,正如您可以从 中看到的全部数据区域被驱逐.

So, as you can see the whole data from the Region is evicted.

这只影响二级缓存.每次运行本机查询时都不会清除第一级缓存(也称为 Session),因为这会分离所有当前的附加实体",从而对实体状态预期产生意想不到的后果.但是在每次查询(HQL 或本机)之前,会话都会被刷新,因此在执行查询之前数据库和会话是同步的,因此在发出新的选择之前,一级缓存是一致的.

This only affects the second-level cache. The first level cache (a.k.a. Session) is not cleared every time you run a native query, because that would detach all your current "attached entities", having unexpected consequences in entity state expectations. But before every query (HQL or native) the session is flushed so the DB and the session are in sync prior to executing the query, hence the 1st level cache is consistent before issuing a new select.

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

A whole region would get invalidated, not the whole second-level cache. An entity defines a cache region, so updating a specific entity table would only remove all the entities that belong to that particular table(s) that were affected by the native query.

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

But overriding the query-space definition associated with a native query is a way to customize Hibernate not to clear the cache region as it would do using the default implementation.

这篇关于Hibernate的原生查询和缓存机制的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-22 08:43