Question

I'm using JBoss 5.1.0 GA together with Hibernate and I'm now trying to enable the second level cache. I've added the following properties to my Hibernate configuration.

<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" />

And I've annotated entities that I expect to change infrequently with the following:

@Cache(usage=CacheConcurrencyStrategy.TRANSACTIONAL)

This is based on my understanding of the documentation.

The application successfully deploys with no scary looking messages (e.g. WARN or ERROR messages in the log stream). For a short period of time I see caching working (I'm using Hibernate statistics to see this), but after a short while I get stack traces of the form (even when logged on as a single user with no remote access whatsoever):

"Transaction attempted to create MYCLASS anew. It has already been created since this transaction started, by another (possibly remote) transaction. We have a concurrent creation event"

Following by a giant stack trace which eventually traces back to a named query that I have made which has the following form:

SELECT x FROM X WHERE x.deleted = false

The named query has no additional annotations for caching.

Any advice on how to solve this problem would be greatly appreciated.

Was it helpful?

Solution

Some questions first:

  1. Is this exception propagated to your application? I mean, are you affected by this, or you are just concerned about the message in the log?
  2. Are all of your entities annotated with Transactional strategy, or only a few of them?
  3. Does your query retrieves eagerly fetched objects of another class?

I would say that the best thing you could do now is to enable DEBUG (or maybe even TRACE) logging for the Cache operations: log4j.logger.org.hibernate.cache=debug This will tell you exactly what Hibernate is doing. I suspect that Hibernate is trying to put an object to the cache, and doing it again once it sees the same object during the same session (maybe as part of another object's tree). There was a timestamp issue for Query Cache some time ago, and the same problem might be occurring here. For instance:

Object A#1
 -- Object B#1

Object A#2
 -- Object B#1

But again, it's a bit hard to predict what the solution is without knowing what the problem would be. And I'm afraid that only Hibernate's log can tell you what the problem really is.

PS: this was meant to be posted as a comment, but this was just too long for it.

OTHER TIPS

Have you tried CacheConcurrencyStrategy.NONSTRICT_READ_WRITE? I read the docs a lot of times and don't know precisely what to choose, but seems to work fine for my projects. I guess the CacheConcurrencyStrategy.TRANSACTIONAL is too much safe and avoid the cache performance in certain circumstances.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top