<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<body link="#355491" alink="#4262a1" vlink="#355491" style="background: #e2e2e2; margin: 0; padding: 20px;">

<div>
        <table cellpadding="0" bgcolor="#FFFFFF" border="0" cellspacing="0" style="border: 1px solid #dadada; margin-bottom: 30px; width: 100%; -moz-border-radius: 6px; -webkit-border-radius: 6px;">
                <tbody>
                        <tr>

                                <td>

                                        <table border="0" cellpadding="0" cellspacing="0" bgcolor="#FFFFFF" style="border: solid 2px #ccc; background: #dadada; width: 100%; -moz-border-radius: 6px; -webkit-border-radius: 6px;">
                                                <tbody>
                                                        <tr>
                                                                <td bgcolor="#000000" valign="middle" height="58px" style="border-bottom: 1px solid #ccc; padding: 20px; -moz-border-radius-topleft: 3px; -moz-border-radius-topright: 3px; -webkit-border-top-right-radius: 5px; -webkit-border-top-left-radius: 5px;">
                                                                        <h1 style="color: #333333; font: bold 22px Arial, Helvetica, sans-serif; margin: 0; display: block !important;">
                                                                        <!-- To have a header image/logo replace the name below with your img tag -->
                                                                        <!-- Email clients will render the images when the message is read so any image -->
                                                                        <!-- must be made available on a public server, so that all recipients can load the image. -->
                                                                        <a href="http://community.jboss.org/index.jspa" style="text-decoration: none; color: #E1E1E1">JBoss Community</a></h1>
                                                                </td>

                                                        </tr>
                                                        <tr>
                                                                <td bgcolor="#FFFFFF" style="font: normal 12px Arial, Helvetica, sans-serif; color:#333333; padding: 20px;  -moz-border-radius-bottomleft: 4px; -moz-border-radius-bottomright: 4px; -webkit-border-bottom-right-radius: 5px; -webkit-border-bottom-left-radius: 5px;"><h3 style="margin: 10px 0 5px; font-size: 17px; font-weight: normal;">
     Hibernate JbossCache integration
</h3>
<span style="margin-bottom: 10px;">
    created by <a href="http://community.jboss.org/people/marilenc">Marilen Corciovei</a> in <i>JBoss Cache</i> - <a href="http://community.jboss.org/docs/DOC-15863">View the full document</a>
</span>
<hr style="margin: 20px 0; border: none; background-color: #dadada; height: 1px;">

<div class="jive-rendered-content"><h2>Introduction</h2><p>JbossCache is a wonderfully complex piece of software. Trying to use&#160; it with Hibernate might seem an easy task at first but in reality it can&#160; also prove wonderfully complicated.</p><p>First question is: <strong>why would you consider using it in the first place?</strong> Compared to ehcache for instance there are a few theoretical&#160; advantages: clustering (scalability), configurability and jmx&#160; monitoring.</p><p>Next question which is not quite obvious is <strong>which version to use?</strong> The answer is a bit complicated since there are a lot of changes in&#160; versions which vary from architectural to configuration points. This&#160; document is concerned with integration of hibernate 3.3.1 with jboss&#160; cache 3.1.0 (Cascabel) as they are shipped in jboss 5.1.0.GA.</p><h2>Choices</h2><p>I think most people consider that cache integration should be a&#160; matter of switching a config option. I cannot argue with this logic and&#160; for them the most appropriate configuration (as described in most&#160; documents) is as following (if using a hibernate-service.xml .har&#160; configuration):</p><div class="wp_syntax"><div class="code"><pre class="xml" style="font-family: monospace;">&lt;property name="cacheRegionFactoryClass"&gt;org.hibernate.cache.jbc2.MultiplexedJBossCacheRegionFactory&lt;/property&gt;</pre></div></div><p>along with activation of second level and query cache:</p><div class="wp_syntax"><div class="code"><pre class="xml" style="font-family: monospace;">&lt;property name="queryCacheEnabled"&gt;true&lt;/property&gt;
&lt;property name="secondLevelCacheEnabled"&gt;true&lt;/property&gt;</pre></div></div><p>This will probably work from start but also from start you will loose one of the advantages: jmx monitoring</p><p>Let&rsquo;s go back to the cacheRegionFactoryClass and it&rsquo;s&#160; hibernate.cache.region.factory_class equivalent. The hibernate&#160; documentation states there are 4 options for this property. Here is my&#160; understanding of them:</p><ul><li><code>SharedJBossCacheRegionFactory</code> will create a Cache (as&#160; in org.jboss.cache.Cache) based on a treecache.xml configuration and use&#160; it for it&rsquo;s caching purposes. You can provide your configuration (in&#160; fact you must provide it) and everything seems perfect except that you&#160; cannot have jmx instrumentation. I have found no way to obtain the Cache&#160; from a SessionFactory and pass it to a CacheJmxWrapper for&#160; instrumentation.</li><li><code>JndiSharedJBossCacheRegionFactory</code> seems the perfect&#160; solution for the above problem as you can create your cache and jmx via a&#160; -jboss-beans.xml configuration and then pass it to hibernate. <strong>Can you? No.</strong> As there is no way to bind the cache to JNDI from the -jboss-beans.xml&#160; configuration. No problem I might say. I will bind it myself. However&#160; the Cache object is not serializable and you will end with an exception.&#160; <strong>No again.</strong></li></ul><pre>javax.naming.CommunicationException [Root exception is java.io.NotSerializableException:</pre><ul><li><code>MultiplexedJBossCacheRegionFactory</code> is the most&#160; recommended solution. What it does is to create multiple Caches managed&#160; by a CacheManager. Remember: you can still have multiple cache regions&#160; with different eviction policies even in a single cache so the reason&#160; for multiple caches seems an extreme case for me such as: having&#160; different passivations or transport options. Note that this CacheManager&#160; is created by hibernate and is not exposed to jmx. If you want to have a&#160; clustering environment with not much fuss you will end up with jboss&#160; default cache manager which also creates several Cache&rsquo;s of it&rsquo;s own.</li><li><code>JndiMultiplexedJBossCacheRegionFactory</code> seems then a&#160; wises choice as it will let you connect/use the existing CacheManager&#160; created by jboss (I will discuss configuration issues later).</li></ul><h2>Configuration</h2><p>Here are some example configurations for the cases described above.</p><h3>treecache.xml for the SharedJbossCacheRegionFactory</h3><p>You have to put it somewhere in the classpath root, for instance in&#160; your .har file. The following example is local, does not uses jgroups&#160; and has a special region for timestamps.</p><div class="wp_syntax"><div class="code"><pre class="xml" style="font-family: monospace;"><span>&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;jbosscache xmlns:xsi="</span><a class="jive-link-external-small" href="http://www.w3.org/2001/XMLSchema-instance" target="_blank">http://www.w3.org/2001/XMLSchema-instance</a><span>" xmlns="urn:jboss:jbosscache-core:config:3.1"&gt;
 
&#160;&#160;&#160;&#160;&#160;&lt;!--
&#160;&#160;&#160;&#160;&#160; isolation levels supported: READ_COMMITTED and REPEATABLE_READ
&#160;&#160;&#160;&#160;&#160; nodeLockingSchemes: mvcc, pessimistic (deprecated), optimistic (deprecated)
&#160;&#160;&#160; --&gt;
&#160;&#160;&#160;&#160;&#160;&lt;locking isolationLevel="REPEATABLE_READ" lockParentForChildInsertRemove="false" lockAcquisitionTimeout="20000" nodeLockingScheme="mvcc" writeSkewCheck="false" useLockStriping="true" concurrencyLevel="500" /&gt;
 
&#160;&#160;&#160;&#160;&#160;&lt;!-- Used to register a transaction manager and participate in ongoing transactions. --&gt;
&#160;&#160;&#160;&#160;&#160;&lt;transaction transactionManagerLookupClass="org.jboss.cache.transaction.GenericTransactionManagerLookup" syncRollbackPhase="false" syncCommitPhase="false" /&gt;
 
&#160;&#160;&#160;&#160;&#160;&lt;!-- Used to register JMX statistics in any available MBean server --&gt;
&#160;&#160;&#160;&#160;&#160;&lt;jmxStatistics enabled="true" /&gt;
 
&#160;&#160;&#160;&#160;&#160;&lt;!-- If region based marshalling is used, defines whether new regions are inactive on startup. --&gt;
&#160;&#160;&#160;&#160;&#160;&lt;startup regionsInactiveOnStartup="true" /&gt;
 
&#160;&#160;&#160;&#160;&#160;&lt;!--
&#160;&#160;&#160;&#160;&#160; Used to register JVM shutdown hooks.
&#160;&#160;&#160;&#160;&#160; hookBehavior: DEFAULT, REGISTER, DONT_REGISTER
&#160;&#160;&#160; --&gt;
&#160;&#160;&#160;&#160;&#160;&lt;shutdown hookBehavior="DEFAULT" /&gt;
 
&#160;&#160;&#160;&#160;&#160;&lt;!-- Used to define async listener notification thread pool size --&gt;
&#160;&#160;&#160;&#160;&#160;&lt;listeners asyncPoolSize="1" asyncQueueSize="100000" /&gt;
 
&#160;&#160;&#160;&#160;&#160;&lt;!-- Used to enable invocation batching and allow the use of Cache.startBatch()/endBatch() methods. --&gt;
&#160;&#160;&#160;&#160;&#160;&lt;invocationBatching enabled="false" /&gt;
 
&#160;&#160;&#160;&#160;&#160;&lt;!-- serialization related configuration, used for replication and cache loading --&gt;
&#160;&#160;&#160;&#160;&#160;&lt;serialization objectInputStreamPoolSize="12" objectOutputStreamPoolSize="14" version="3.0.0" marshallerClass="org.jboss.cache.marshall.VersionAwareMarshaller" useLazyDeserialization="false" useRegionBasedMarshalling="false" /&gt;
 
&#160;&#160;&#160;&#160;&#160;&lt;!--
&#160;&#160;&#160;&#160;&#160; Eviction configuration.&#160; WakeupInterval defines how often the eviction thread runs, in milliseconds.&#160; 0 means
&#160;&#160;&#160;&#160;&#160; the eviction thread will never run.
&#160;&#160; --&gt;
&#160;&#160;&#160;&#160;&#160;&lt;eviction wakeUpInterval="500"&gt;
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&lt;default algorithmClass="org.jboss.cache.eviction.LRUAlgorithm" eventQueueSize="200000"&gt;
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&lt;property name="maxNodes" value="5000" /&gt;
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&lt;property name="timeToLive" value="40000" /&gt;
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&lt;/default&gt;
 
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&lt;region name="/TS" algorithmClass="org.jboss.cache.eviction.NullEvictionAlgorithm"&gt;
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&lt;/region&gt;
&#160;&#160;&#160;&#160;&#160;&lt;/eviction&gt;
&lt;/jbosscache&gt;</span></pre></div></div><h3>-jboss-beans.xml deployement</h3><p>Of a cache which cannot be bound to jndi and passed to SharedJbossCacheRegionFactory, also local:</p><div class="wp_syntax"><div class="code"><pre class="xml" style="font-family: monospace;">&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;deployment xmlns="urn:jboss:bean-deployer:2.0"&gt;
 
&#160;&#160; &lt;!-- First we create a Configuration object for the cache --&gt;
&#160;&#160; &lt;bean name="DiapasonCacheConfig"
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; class="org.jboss.cache.config.Configuration"&gt;
&#160;&#160;&#160;&#160;&#160; &lt;property name="runtimeConfig"&gt;
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;bean class="org.jboss.cache.config.RuntimeConfig"&gt;
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;property name="transactionManager"&gt;
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;inject bean="jboss:service=TransactionManager" 
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; property="TransactionManager"/&gt;
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;/property&gt;
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;!--
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;property name="muxChannelFactory"&gt;&lt;inject bean="JChannelFactory"/&gt;&lt;/property&gt;
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; --&gt;
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;/bean&gt;
&#160;&#160;&#160;&#160;&#160; &lt;/property&gt;
 
&#160;&#160;&#160;&#160;&#160; &lt;property name="multiplexerStack"&gt;udp&lt;/property&gt;
&#160;&#160;&#160;&#160;&#160; &lt;property name="clusterName"&gt;Diapason-EntityCache&lt;/property&gt;
&#160;&#160;&#160;&#160;&#160; &lt;property name="isolationLevel"&gt;REPEATABLE_READ&lt;/property&gt;
&#160;&#160;&#160;&#160;&#160; &lt;property name="cacheMode"&gt;LOCAL&lt;/property&gt;
&#160;&#160;&#160;&#160;&#160; &lt;property name="stateRetrievalTimeout"&gt;15000&lt;/property&gt;
&#160;&#160;&#160;&#160;&#160; &lt;property name="syncReplTimeout"&gt;20000&lt;/property&gt;
&#160;&#160;&#160;&#160;&#160; &lt;property name="lockAcquisitionTimeout"&gt;15000&lt;/property&gt;
&#160;&#160;&#160;&#160;&#160; &lt;property name="exposeManagementStatistics"&gt;true&lt;/property&gt;
&#160;&#160; &lt;/bean&gt;
 
 
&#160;&#160; &lt;!-- Factory to build the Cache. --&gt;
&#160;&#160; &lt;bean name="DefaultCacheFactory" class="org.jboss.cache.DefaultCacheFactory"&gt;&#160;&#160;&#160;&#160;&#160; 
&#160;&#160;&#160;&#160;&#160; &lt;constructor factoryClass="org.jboss.cache.DefaultCacheFactory"
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; factoryMethod="getInstance" /&gt;
&#160;&#160; &lt;/bean&gt;
 
&#160;&#160; &lt;!-- The cache itself --&gt;
&#160;&#160; &lt;bean name="DiapasonCache" class="org.jboss.cache.Cache"&gt;
&#160;&#160;&#160;&#160;&#160; &lt;constructor factoryMethod="createCache"&gt;
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;factory bean="DefaultCacheFactory"/&gt;
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;parameter class="org.jboss.cache.config.Configuration"&gt;&lt;inject bean="DiapasonCacheConfig"/&gt;&lt;/parameter&gt;
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;parameter class="boolean"&gt;false&lt;/parameter&gt;
&#160;&#160;&#160;&#160;&#160; &lt;/constructor&gt;
&#160;&#160; &lt;/bean&gt;
 
&#160;&#160; &lt;!-- JMX Management --&gt;
&#160;&#160; &lt;bean name="DiapasonCacheJmxWrapper" class="org.jboss.cache.jmx.CacheJmxWrapper"&gt;
&#160;&#160;&#160;&#160;&#160; &lt;annotation&gt;@org.jboss.aop.microcontainer.aspects.jmx.JMX(name="jboss.cache:service=DiapasonTreeCache", exposedInterface=org.jboss.cache.jmx.CacheJmxWrapperMBean.class, registerDirectly=true)&lt;/annotation&gt;
&#160;&#160;&#160;&#160;&#160; &lt;constructor&gt;
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;parameter&gt;&lt;inject bean="DiapasonCache"/&gt;&lt;/parameter&gt;
&#160;&#160;&#160;&#160;&#160; &lt;/constructor&gt;
&#160;&#160; &lt;/bean&gt;
&lt;!-- a bean I tried to use to register the cache to jndi, ignore
&#160;&#160;&#160;&#160;&#160;&lt;bean name="CacheX" class="ro.len.CacheX"&gt;
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&lt;property name="cache"&gt;&lt;inject bean="DiapasonCache"/&gt;&lt;/property&gt;
&#160;&#160; &lt;/bean&gt;
--&gt;
&lt;/deployment&gt;</pre></div></div><h3>MultiplexedJBossCacheRegionFactory</h3><p>No config is needed in this case as hibernate will use 2 files <code>jbc2-configs.xml</code> and <code>jgroups-stacks.xml</code> both found in <code>hibernate-jbosscache2.jar</code>.&#160; Of course if you want to take advantage of the configurability of Jboss&#160; Cache you will have to take these files and adapt them to your need.</p><h3>JndiMultiplexedJBossCacheRegionFactory</h3><p>This option will give you most of the things you want and can be configured as following:</p><div class="wp_syntax"><div class="code"><pre class="xml" style="font-family: monospace;">&lt;property name="cacheRegionFactoryClass"&gt;org.hibernate.cache.jbc2.JndiMultiplexedJBossCacheRegionFactory&lt;/property&gt;
&lt;property name="deployedCacheManagerJndiName"&gt;java:/CacheManager&lt;/property&gt;</pre></div></div><p>This will make use of the existing CacheManager which is registered&#160; to JNDI. However if using the &ldquo;default&#8221; configuration for jboss this is&#160; not the case. You will need to copy jboss-cache-manager.sar and&#160;&#160; jgroups-channelfactory.sar from the all/deploy/cluster to&#160; default/deploy/cluster along with an extra jar for pojo cache&#160; (jbosscache-pojo.jar, still don&rsquo;t know the use of that).</p><p>In order to configure your cache you will need to edit the&#160; jboss-cache-manager-jboss-beans.xml file notably the optimistic-entity&#160; entry which hibernate will use.</p><h2>Conclusions</h2><p>You might ask: <strong>why use jboss cache after all?</strong> it does seem a bit too complicated. I think you can find at least the following benefits:</p><ul><li>Configurability related to <strong>cache regions</strong>. This&#160; seems the most interesting benefit from my point of view, can be done in&#160; any of the previous configs and does not require a CacheManager or&#160; clustering.This is where you can configure various eviction policies.&#160; You might want for instance some data to be evicted much slower than&#160; other or some data never to evicted. This means of course some mapping&#160; (.hbm) changes in case of entities consisting in adding the region&#160; attribute to the cache part of the mapping and some code change in case&#160; of queries. </li><li><strong>JMX</strong> is of great use. First, it allows to see that&#160; the eviction configured really works and second it shows lock problems&#160; which unfortunately where a problem in previous jboss cache versions (as&#160; in jboss 4.2.2 GA). Let&rsquo;s hope it will no longer be the case.</li><li>Of least importance for most people it will be <strong>clustering</strong>.&#160; But even if initially it might be of reduced importance it&rsquo;s good to&#160; know if you ever need it support is already there and only some&#160; configuration is required</li></ul><h2>Links</h2><p>Finally here are some links which I read a lot of times in the&#160; process of testing these configurations and are the base for this&#160; article which intended to be much more shorter:</p><ul><li><a class="jive-link-external-small" href="http://docs.jboss.org/jbosscache/3.1.0.CR1/userguide_en/html_single/index.html">documentation for this cache version</a></li><li><a class="jive-link-external-small" href="http://docs.jboss.org/jbossclustering/hibernate-caching/3.3/en-US/html_single/index.html">hibernate, jboss cache integration</a></li><li><a class="jive-link-message-small" href="http://community.jboss.org/message/270922#270922">post discussing the jmx/jndi exposure</a> (found it later but describes similar observations)</li><li><a class="jive-link-external-small" href="http://www.len.ro/2010/02/jboss-migration-4-2-2-ga-to-5-1-0-ga/">migration from jboss 4 to 5 document</a> (why I arrived to this problem)</li></ul></div>

<div style="background-color: #f4f4f4; padding: 10px; margin-top: 20px;">
    <p style="margin: 0;">Comment by <a href="http://community.jboss.org/docs/DOC-15863">going to Community</a></p>

        <p style="margin: 0;">Create a new document in JBoss Cache at <a href="http://community.jboss.org/choose-container!input.jspa?contentType=102&containerType=14&container=2052">Community</a></p>
</div></td>
                        </tr>
                    </tbody>
                </table>


                </td>
            </tr>
        </tbody>
    </table>

</div>

</body>
</html>