有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java缓存不适用于Spring3.0、Hibernate3.6和Ehcache2.6.6

我们正在尝试让缓存在我们的应用程序中工作,并且很难让它真正工作。我们没有一个非常复杂的配置,至少对于应用程序的这一部分来说是这样,所以这真的很令人沮丧,我最后不得不求助于StackOverflow社区

首先,目前我们还停留在Spring3.0和Hibernate3.6上,所以使用新的Spring3.1@Cacheable注释和所有其他东西对我们来说都不是一个选择

我已经将我们的堆栈版本放在主题中,我们有一个非常典型的堆栈配置:

  • 我们的Hibernate实体是用@Entity定义的,DAO是用@Repository定义的,服务是用@Service定义的
  • 使用@Transactional设置事务边界
  • 我通过将ehcache核心添加到pom中来添加缓存。xml并将以下属性添加到Hibernate属性映射:
<prop key="hibernate.cache.use_second_level_cache">true</prop>
<prop key="hibernate.cache.use_query_cache">true</prop>
<prop key="hibernate.cache.region.factory_class">net.sf.ehcache.hibernate.SingletonEhCacheRegionFactory</prop>

然后,我将@Cache注释添加到实体类中,如下所示:

@Entity
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE, region = "config")
public class Configuration extends AbstractHibernateEntity implements Serializable {

老实说,我以为我完蛋了。感谢我如此轻松地配置缓存!你可以看到它在工作,当缓存上线时,日志中有很多消息。太好了

结果是缓存已经联机,没有缓存任何内容。我现在已经连续两天在研究这个问题,不知道为什么我的对象没有得到缓存。我已尝试将<cache name="..."/>添加到我的ehcache中。xml,指定我的@Cache注释上的区域,检查缓存统计信息,等等。我已经为网络添加了调试日志记录。旧金山。ehcache组织。冬眠缓存包。我只是不明白是什么阻止了它将对象保存到缓存中并在那里访问它们

在我们意识到我们的web应用程序没有缓存之后,我回到依赖库中,意识到它们也没有缓存(我在单元测试中添加了缓存,以确保缓存没有破坏单元测试;它没有破坏单元测试,但可能这只是因为它没有缓存)。因此,我一直在研究我们的一个较低级别的依赖项,我想如果我能找出如何使它在该级别工作,我可以将其提升到web应用程序级别。这是一个伟大的理论,只是我甚至不能让它在较低的层次上工作

在我的日志中,我收到了很多信息。下面是来自net的调试输出示例。旧金山。ehcache

14:03:20,795  INFO                           net.sf.ehcache: 284 - CACHE HITS:  0
14:03:20,796  INFO                           net.sf.ehcache: 284 - IN-MEM HITS: 0
14:03:20,796  INFO                           net.sf.ehcache: 284 - CACHE MISS:  0
14:03:20,796  INFO                           net.sf.ehcache: 284 - IN-MEM MISS: 0
14:03:20,796  INFO                           net.sf.ehcache: 284 - EVICTIONS:   0
14:03:20,797  INFO                           net.sf.ehcache: 284 - MEM OBJ CT:  0
14:03:20,886 DEBUG bernate.regions.EhcacheGeneralDataRegion: 211 - key: xhbm_configuration_data value: 5643835231789056
14:03:20,890 DEBUG bernate.regions.EhcacheGeneralDataRegion: 211 - key: xhbm_configuration value: 5643835231805440
14:03:20,891 DEBUG bernate.regions.EhcacheGeneralDataRegion: 211 - key: xhbm_configuration_data value: 5643834986045441
14:03:20,891 DEBUG bernate.regions.EhcacheGeneralDataRegion: 211 - key: xhbm_configuration value: 5643834986045441
14:03:20,897 DEBUG bernate.regions.EhcacheGeneralDataRegion: 211 - key: xhbm_configuration_data value: 5643835231834112
14:03:20,898 DEBUG bernate.regions.EhcacheGeneralDataRegion: 211 - key: xhbm_configuration value: 5643835231838208
14:03:20,898 DEBUG bernate.regions.EhcacheGeneralDataRegion: 211 - key: xhbm_configuration_data value: 5643834986078209
14:03:20,899 DEBUG bernate.regions.EhcacheGeneralDataRegion: 211 - key: xhbm_configuration value: 5643834986078209

组织中。冬眠缓存log,我得到很多这样的东西:

14:47:26,077 DEBUG rg.hibernate.cache.UpdateTimestampsCache: 168 - Pre-invalidating space [xhbm_configuration_data]
14:47:26,081 DEBUG rg.hibernate.cache.UpdateTimestampsCache: 168 - Pre-invalidating space [xhbm_configuration]
14:47:26,082 DEBUG rg.hibernate.cache.UpdateTimestampsCache: 168 - Invalidating space [xhbm_configuration_data], timestamp: 5643845820751872
14:47:26,082 DEBUG rg.hibernate.cache.UpdateTimestampsCache: 168 - Invalidating space [xhbm_configuration], timestamp: 5643845820751872
14:47:26,089 DEBUG rg.hibernate.cache.UpdateTimestampsCache: 168 - Pre-invalidating space [xhbm_configuration_data]
14:47:26,091 DEBUG rg.hibernate.cache.UpdateTimestampsCache: 168 - Pre-invalidating space [xhbm_configuration]
14:47:26,092 DEBUG rg.hibernate.cache.UpdateTimestampsCache: 168 - Invalidating space [xhbm_configuration_data], timestamp: 5643845820792832
14:47:26,092 DEBUG rg.hibernate.cache.UpdateTimestampsCache: 168 - Invalidating space [xhbm_configuration], timestamp: 5643845820792832
14:47:26,125 DEBUG rg.hibernate.cache.UpdateTimestampsCache: 168 - Pre-invalidating space [xhbm_configuration_data]
14:47:26,130 DEBUG rg.hibernate.cache.UpdateTimestampsCache: 168 - Pre-invalidating space [xhbm_configuration]
14:47:26,131 DEBUG rg.hibernate.cache.UpdateTimestampsCache: 168 - Invalidating space [xhbm_configuration_data], timestamp: 5643845820952576
14:47:26,132 DEBUG rg.hibernate.cache.UpdateTimestampsCache: 168 - Invalidating space [xhbm_configuration], timestamp: 5643845820952576

我真的不知道从这里还能说些什么。完整代码可以从位于https://bitbucket.org/rherrick/nrg_config的我的Bitbucket repo(它是Mercurial,不是git)或位于https://dl.dropboxusercontent.com/u/42711610/nrg_config.zip的Dropbox的zip文件中获得。您应该能够通过以下方式从Maven运行单元测试:

mvn clean install

如果有人能帮我弄清楚这里到底出了什么问题,我会非常高兴的!你不想让我欣喜若狂吗?我知道我知道:)

说真的,对于在这个问题上提供的任何帮助,我们会提前表示感谢,之后也会表示感谢


共 (2) 个答案

  1. # 1 楼答案

    据我所知,只有在Session上调用load{}、list等时,才会使用对象的二级缓存。我在你的代码中看不到这样的调用

    只有在对QueryCriteria对象调用setCacheable时,才会使用查询缓存。再说一次,您永远不会在代码中调用该方法

  2. # 2 楼答案

    亚历山大

    你在正确的轨道上,但这只是导致问题的几个因素之一。实际上有三个因素:

    1. 我们的代码实际上是在调用load()、get()、list()等,但它主要包含在我们的框架代码中。我仔细阅读并模板化了一堆代码,以明确地强制缓存。这开始了一些缓存
    2. JPA/Hibernate实体不应该初始化任何东西!我们有一个基类,它在实例化时设置了几个标志和时间戳。当检索对象时,这会使对象看起来脏兮兮的,并且需要对数据库进行一次完整的运行。对于我们的框架来说,这确实是一个大问题
    3. 设置瞬态属性时要注意事务边界。当您进入并退出标记为@Transactional的方法时,对对象的任何更改都将被持久化,无论您是否调用了会话。是否在该对象上保存(),as described here。这导致对象经常无法与缓存版本匹配(虽然我原以为对象的修改版本会与缓存匹配,但这似乎没有发生)

    最后,这真的很难诊断,主要是因为这不是一个单一的因素,而是由许多不同的因素共同导致的