User development,
The document "JBossCacheHibernateAlignment", was updated Feb 22, 2010
by Manik Surtani.
To view the document, visit:
http://community.jboss.org/docs/DOC-10266#cf
Document:
--------------------------------------------------------------
h3. What is this page about?
This page is about aligning JBossCache and Hibernate better in ideological terms, with a
goal to improve the integration of and interoperability between these two products and
make JBossCache the default caching provider in Hibernate.
h3. Discussion
Details of discussions about this subject are on
http://www.jboss.org/index.html?module=bb&op=viewtopic&t=88929
h3. Issues at Hand
1. Hibernate's caching needs involve caching 4 separate types of objects: entities,
collections, queries and update-timestamps (related to queries), each requiring different
caching characteristics.
2. When dealing with entities, JBossCache has a concept of a put(), which puts data into
the cache. Hibernate, on the other hand, has 2 separate notions of a put() - one is where
data is READ from the database and put into the cache, and the other is where data is
WRITTEN to the database and put into the cache. The two cases drive separate requirements
and behavioural patterns for locking, etc.
3. When dealing with entities, the way Hibernate organises data in the tree structure of
JBossCache leads to inefficiencies and contention with concurrent threads.
4. Replicating user types can cause issues when the classloader that loads JBoss Cache
does not have visibility to the types being replicated. See
http://www.jboss.com/index.html?module=bb&op=viewtopic&t=95748 for details.
5. JBoss Cache and Hibernate both make use of the JTA Synchronization interface, with an
implicit assumption that the Hibernate synchronization will be called before the JBC one.
This is an invalid assumption, as the JTA spec makes no guarantee of ordering between
synchronizations. The fact that this usually works is due to an implementation detail of
various transaction managers. We have found that with JBossTS it often fails. See
http://www.jboss.com/index.html?module=bb&op=viewtopic&t=97247 for further
discussion.
6. JBoss Cache 1.x and 2.x are API incompatible. We need to develop a strategy for dealing
in the Hibernate code base with the existence of two incompatible JBC flavors.
7. Using JBossCache as second level cache and optimistic locking, rollbacks can still
happen in systems under load as concurrent transactions could be modifying data in the
cache. This is a currently pushed back to the Hibernate clients.
http://opensource.atlassian.com/projects/hibernate/browse/HHH-2340
h3. Solutions
Based on some of the ideas discussed on the forum threads above, as well as phone and
face-to-face discussions between JBossCache and Hibernate folk, we have a few steps that
can be taken to overcome the issues at hand.
1. The solution for this is:
* In the short term, for Hibernate to provide a TreeCacheProvider that creates 3
JBossCache instances, one for each cache type. The JBossCache instances should be
configured using
http://jira.jboss.com/jira/browse/JBCACHE-812
http://labs.jboss.com/file-access/default/members/jbosscache/freezone/doc...
to significantly reduce the "weight" of multiple JBoss Cache instances.
* In the long term, to define the different caches explicitly within Hibernate.
2. The solution here is to create a putForExternalRead() method in JBossCache, which
Hibernate could call when doing a database READ. The characteristics of such a method
would be:
* Suspend all ongoing TXs.
* If using pessimistic locking, use weaker locking semantics (READ_UNCOMMITTED? - needs
further discussion)
* Quieter logging. Errors and the like that would otherwise raise alarm bells should be
suppressed since this is a non-critical call.
* Run this call in a separate thread, so it does not block (? Needs discussion too -
should this be the responsibility of the TreeCacheProvider in Hibernate?)
3. Consider the use of hash buckets under the 'type' node so that contention is
reduced?
4. The Hibernate Cache implementation(s) for JBC should make use of the JBC region-based
marshalling feature.
5. No clear solution at this point.
6. Different providers? We currently have TreeCacheProvider and
OptimisticTreeCacheProvider. How about a
org.hibernate.cache.jbosscache200.PessimisticCacheProvider and
org.hibernate.cache.jbosscache200.OptimisticCacheProvider ??
7. Hibernate should either retry or JBossCache should fail silently on this. As long as
the data is stored in the db correctly, failure putting the data in the cache could fail
silently. Next time someone requests the entity, it'd be retrieved from db and put in
the cache.
h3. Update (2007/07/04)
There are currently a bunch of EJB3 clustered entity test failures in AS trunk due to a
bad interaction between Hibernate 3.2.4.SP1 and JBoss Cache 2.0.0. Basically, this is a
temporary mismatch between the Hibernate and JBC releases currently integrated in AS
trunk. There's work in Hibernate Core's trunk for the 3.3 release that can let us
resolve this, but for now the tests are going to fail.
Problem is the integration layer ends up calling the above discussed JBC
putForExternalRead() method when it needs to cache something in the
"UpdateTimestampsCache". JBC treats a call to this method as a no-op if the
cache node in question already exists. This is new behavior in JBC 2.0. It's the
necessary and intended behavior when the method is called for caching entities and
collections. But when it's called for the UpdateTimestampsCache, it causes problems.
The Hibernate 3.3. codebase gives us the flexibility to call a different method for the
UpdateTimestampsCache call; to fix the problem we need determine the exact behavior we
want for the UpdateTimestampsCache call and make the appropriate call to JBC.
The JBC and Hibernate teams will be meeting the week of July 23rd to sort through the
various issues on discussed on this page; the UpdateTimestampsCache issue will be one of
the items we'll resolve.
--------------------------------------------------------------