【问题标题】:Why does Hibernate 2nd level statics show different values then CacheManager为什么 Hibernate 2nd level statics 显示不同的值然后 CacheManager
【发布时间】:2019-04-02 16:42:35
【问题描述】:

使用 Hibernate 4.3.11 和 Ehcache 2.7.0

为什么 Hibernates getStatistics() 返回的命中/未命中与 CacheManager 返回的值不匹配。我为单个类启用了二级缓存。

所以用这段代码

Statistics stats = HibernateUtil.getFactory().getStatistics();
    writeToBothLogs("Report:" + currentReportId + ":DbConnect:" + stats.getConnectCount());
    writeToBothLogs("Report:" + currentReportId + ":DbQueries:" + stats.getQueryExecutionCount());
    writeToBothLogs("Report:" + currentReportId + ":2ndLevelPut:" + stats.getSecondLevelCachePutCount());
    writeToBothLogs("Report:" + currentReportId + ":2ndLevelHit:" + stats.getSecondLevelCacheHitCount());
    writeToBothLogs("Report:" + currentReportId + ":2ndLevelMiss:" + stats.getSecondLevelCacheMissCount());


    String[] cacheNames = CacheManager.getInstance().getCacheNames();
    for(String cacheName:cacheNames)
    {
        SecondLevelCacheStatistics secondLeveleStats = stats.getSecondLevelCacheStatistics(cacheName);
        writeToBothLogs("Report:" + currentReportId + ":"+cacheName+":2ndLevelPut:" +  secondLeveleStats.getPutCount());
        writeToBothLogs("Report:" + currentReportId + ":"+cacheName+":2ndLevelHit:" + secondLeveleStats.getHitCount());
        writeToBothLogs("Report:" + currentReportId + ":"+cacheName+":2ndLevelMiss:" + secondLeveleStats.getMissCount());
        writeToBothLogs("Report:" + currentReportId + ":"+cacheName+":2ndLevelSizeInMemory:" + secondLeveleStats.getSizeInMemory());

        Cache cache = CacheManager.getInstance().getCache(cacheName);
        writeToBothLogs("CacheName:"+cacheName
                +":Put:"+cache.getStatistics().cachePutCount()
                +":Hit:"+cache.getStatistics().cacheHitCount()
                +":Miss:"+cache.getStatistics().cacheMissCount()
                +":Size:"+cache.getSize()
        );

    }

    writeToBothLogs("Report:" + currentReportId + ":DeleteCount:" + stats.getEntityDeleteCount());
    writeToBothLogs("Report:" + currentReportId + ":InsertCount:" + stats.getEntityInsertCount());
    writeToBothLogs("Report:" + currentReportId + ":FetchCount:" + stats.getEntityFetchCount());
    writeToBothLogs("Report:" + currentReportId + ":UpdateCount:" + stats.getEntityUpdateCount());
    writeToBothLogs("Report:" + currentReportId + ":LoadCount:" + stats.getEntityLoadCount());

我明白了:

29/10/2018 17.16.35:GMT:SummaryReportSection:writeToBothLogs:SEVERE: Report:295:2ndLevelPut:778
29/10/2018 17.16.35:GMT:SummaryReportSection:writeToBothLogs:SEVERE: Report:295:2ndLevelHit:0
29/10/2018 17.16.35:GMT:SummaryReportSection:writeToBothLogs:SEVERE: Report:295:2ndLevelMiss:0
29/10/2018 17.16.35:GMT:SummaryReportSection:writeToBothLogs:SEVERE: Report:295:com.jthink.songlayer.Song:2ndLevelPut:778
29/10/2018 17.16.35:GMT:SummaryReportSection:writeToBothLogs:SEVERE: Report:295:com.jthink.songlayer.Song:2ndLevelHit:0
29/10/2018 17.16.35:GMT:SummaryReportSection:writeToBothLogs:SEVERE: Report:295:com.jthink.songlayer.Song:2ndLevelMiss:0
29/10/2018 17.16.35:GMT:SummaryReportSection:writeToBothLogs:SEVERE: Report:295:com.jthink.songlayer.Song:2ndLevelSizeInMemory:1672432
29/10/2018 17.16.35:GMT:SummaryReportSection:writeToBothLogs:SEVERE: CacheName:com.jthink.songlayer.Song:Put:1333:Hit:2088:Miss:223:Size:223

所以 Hibernate 没有显示命中,但 CacheManager 确实显示了命中,是什么造成了这种差异?

顺便说一句,我的 ehcache.xml 文件是

<?xml version="1.0" encoding="UTF-8"?>
<ehcache>
    <defaultCache
            maxEntriesLocalHeap="500"
            eternal="false"
            diskExpiryThreadIntervalSeconds="120"
            memoryStoreEvictionPolicy="LRU"
    >
    <persistence strategy="localTempSwap"/>
    </defaultCache>
    <cache
            name="com.jthink.songlayer.Song"
            maxEntriesLocalHeap="5000"
            eternal="false"
            memoryStoreEvictionPolicy="LRU"
    >
    <persistence strategy="localTempSwap"/>
    </cache>
</ehcache>

【问题讨论】:

    标签: hibernate ehcache hibernate-4.x


    【解决方案1】:

    确保:

    • 查询缓存已启用:

      hibernate.cache.use_query_cache=true

    • 查询结果被缓存:

      query.setHint("org.hibernate.cacheable", "true")

    二级缓存将在插入/更新时更新。

    如果查询缓存被禁用或查询结果不可缓存,则在调用 TypedQuery.getResultList() 之类的操作时不会查询它。


    至少这是 Hibernate 5.3.6 中的行为。命中/未命中统计信息仅在调用 org.hibernate.event.internal.DefaultLoadEventListener.onLoad() 时更新。如果这些属性中的任何一个为 false,则在列出结果时永远不会触发此事件。

    【讨论】:

    • 好的,所以我没有启用查询缓存,但您还没有真正解释为什么 statsare 在未启用的情况下有所不同。
    猜你喜欢
    • 2022-01-22
    • 2011-03-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-12
    • 2012-05-25
    • 2018-11-09
    相关资源
    最近更新 更多