0

我将 JBoss 5.1.0 GA 与 Hibernate 一起使用,现在我正在尝试启用二级缓存。我已将以下属性添加到我的 Hibernate 配置中。

<property name="hibernate.cache.use_query_cache" value="true"/>
<property name="hibernate.cache.use_second_level_cache" value="true"/>
<property name="hibernate.cache.region.factory_class" value="org.hibernate.cache.jbc2.MultiplexedJBossCacheRegionFactory"/>
<property name="hibernate.cache.jbc2.query.localonly" value="true"/>
<property name="hibernate.cache.region_prefix" value="my_prefix" />

我已经注释了我希望不经常更改的实体,如下所示:

@Cache(usage=CacheConcurrencyStrategy.TRANSACTIONAL)

这是基于我对文档的理解。

应用程序成功部署,没有可怕的消息(例如日志流中的 WARN 或 ERROR 消息)。在很短的时间内,我看到缓存工作(我正在使用 Hibernate 统计信息来查看这一点),但不久之后,我得到了表单的堆栈跟踪(即使以没有任何远程访问权限的单个用户身份登录):

“事务试图重新创建 MYCLASS。自此事务开始以来,它已经由另一个(可能是远程)事务创建。我们有一个并发创建事件”

接下来是一个巨大的堆栈跟踪,最终追溯到我所做的一个命名查询,它具有以下形式:

SELECT x FROM X WHERE x.deleted = false

命名查询没有用于缓存的附加注释。

任何有关如何解决此问题的建议将不胜感激。

4

2 回答 2

1

先问几个问题:

  1. 此异常是否传播到您的应用程序?我的意思是,您是否受此影响,或者您只是关心日志中的消息?
  2. 您的所有实体是否都使用事务策略进行了注释,还是仅其中几个?
  3. 您的查询是否检索到另一个类的急切获取的对象?

我想说你现在能做的最好的事情是为缓存操作启用调试(甚至可能是跟踪)日志记录:log4j.logger.org.hibernate.cache=debug这将准确地告诉你 Hibernate 正在做什么。我怀疑Hibernate 正在尝试将一个对象放入缓存,并在同一会话期间看到同一对象后再次执行此操作(可能是另一个对象树的一部分)。前段时间查询缓存有一个时间戳问题,这里可能会出现同样的问题。例如:

对象 A#1
 -- 对象 B#1

对象 A#2
 -- 对象 B#1

但同样,在不知道问题是什么的情况下,很难预测解决方案是什么。而且恐怕只有 Hibernate 的日志才能告诉您真正的问题是什么。

PS:这是作为评论发布的,但这对它来说太长了。

于 2011-01-06T12:33:18.930 回答
0

您是否尝试过 CacheConcurrencyStrategy.NONSTRICT_READ_WRITE?我读了很多次文档,不知道该选择什么,但似乎对我的项目很有效。我猜 CacheConcurrencyStrategy.TRANSACTIONAL 太安全了,在某些情况下会避免缓存性能。

于 2011-01-06T12:42:45.337 回答