Chapter 24. Clustered Entity EJBs
24.1. Entity Bean in EJB 3.0
24.1.1. Configure the distributed cache
- If you persist a cache-enabled entity bean instance to the database via the entity manager, the entity will be inserted into the cache.
- If you update an entity bean instance, and save the changes to the database via the entity manager, the entity will be updated in the cache.
- If you remove an entity bean instance from the database via the entity manager, the entity will be removed from the cache.
- If loading a cached entity from the database via the entity manager, and that entity does not exist in the database, it will be inserted into the cache.
persistence.xml, like so:
<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/persistence"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd">
<persistence-unit name="tempdb" transaction-type="JTA">
<jta-data-source>java:/DefaultDS</jta-data-source>
<properties>
<property name="hibernate.cache.use_second_level_cache" value="true"/>
<property name="hibernate.cache.use_query_cache" value="true"/>
<property name="hibernate.cache.region.factory_class" value="org.hibernate.cache.jbc2.JndiMultiplexedJBossCacheRegionFactory"/>
<!-- region factory specific properties -->
<property name="hibernate.cache.region.jbc2.cachefactory" value="java:CacheManager"/>
<property name="hibernate.cache.region.jbc2.cfg.entity" value="mvcc-entity"/>
<property name="hibernate.cache.region.jbc2.cfg.collection" value="mvcc-entity"/>
</properties>
</persistence-unit>
</persistence>
- hibernate.cache.use_second_level_cache
- Enables second-level caching of entities and collections.
- hibernate.cache.use_query_cache
- Enables second-level caching of queries.
- hibernate.cache.region.factory_class
- Defines the
RegionFactoryimplementation that dictates region-specific caching behavior. Hibernate ships with 2 types of JBoss Cache-based second-level caches: shared and multiplexed.A shared region factory uses the same Cache for all cache regions - much like the legacy CacheProvider implementation in older Hibernate versions.Hibernate ships with 2 shared region factory implementations:- org.hibernate.cache.jbc2.SharedJBossCacheRegionFactory
- Uses a single JBoss Cache configuration, from a newly instantiated CacheManager, for all cache regions.
Table 24.1. Additional properties for SharedJBossCacheRegionFactory
Property Default Description hibernate.cache.region.jbc2.cfg.shared treecache.xml The classpath or file system resource containing the JBoss Cache configuration settings. hibernate.cache.region.jbc2.cfg.jgroups.stacks org/hibernate/cache/jbc2/builder/jgroups-stacks.xml The classpath or file system resource containing the JGroups protocol stack configurations. - org.hibernate.cache.jbc2.JndiSharedJBossCacheRegionFactory
- Uses a single JBoss Cache configuration, from an existing CacheManager bound to JNDI, for all cache regions.
Table 24.2. Additional properties for JndiSharedJBossCacheRegionFactory
Property Default Description hibernate.cache.region.jbc2.cfg.shared Required JNDI name to which the shared Cacheinstance is bound.
A multiplexed region factory uses separate Cache instances, using optimized configurations for each cache region.Table 24.3. Common properties for multiplexed region factory implementations
Property Default Description hibernate.cache.region.jbc2.cfg.entity optimistic-entity The JBoss Cache configuration used for the entity cache region. Alternative configurations: mvcc-entity, pessimistic-entity, mvcc-entity-repeatable, optimistic-entity-repeatable, pessimistic-entity-repeatable hibernate.cache.region.jbc2.cfg.collection optimistic-entity The JBoss Cache configuration used for the collection cache region. The collection cache region typically uses the same configuration as the entity cache region. hibernate.cache.region.jbc2.cfg.query local-query The JBoss Cache configuration used for the query cache region. By default, cached query results are not replicated. Alternative configurations: replicated-query hibernate.cache.region.jbc2.cfg.ts timestamps-cache The JBoss Cache configuration used for the timestamp cache region. If query caching is used, the corresponding timestamp cache must be replicating, even if the query cache is non-replicating. The timestamp cache region must never share the same cache as the query cache. Hibernate ships with 2 shared region factory implementations:- org.hibernate.cache.jbc2.MultiplexedJBossCacheRegionFactory
- Uses separate JBoss Cache configurations, from a newly instantiated CacheManager, per cache region.
Table 24.4. Additional properties for MultiplexedJBossCacheRegionFactory
Property Default Description hibernate.cache.region.jbc2.configs org/hibernate/cache/jbc2/builder/jbc2-configs.xml The classpath or file system resource containing the JBoss Cache configuration settings. hibernate.cache.region.jbc2.cfg.jgroups.stacks org/hibernate/cache/jbc2/builder/jgroups-stacks.xml The classpath or file system resource containing the JGroups protocol stack configurations. - org.hibernate.cache.jbc2.JndiMultiplexedJBossCacheRegionFactory
- Uses separate JBoss Cache configurations, from a JNDI-bound CacheManager, see Section 21.2.1, “The JBoss Enterprise Application Platform CacheManager Service”, per cache region.
Table 24.5. Additional properties for JndiMultiplexedJBossCacheRegionFactory
Property Default Description hibernate.cache.region.jbc2.cachefactory Required JNDI name to which the CacheManagerinstance is bound.
24.1.2. Configure the entity beans for cache
@org.hibernate.annotations.Cache annotation to tag entity beans that needs to be cached.
@Entity
@Cache(usage = CacheConcurrencyStrategy.TRANSACTIONAL)
public class Account implements Serializable
{
// ... ...
}
jboss-cache-manager-jboss-beans.xml. For instance, you can specify the size of the cache. If there are too many objects in the cache, the cache can evict the oldest or least used objects, depending on configuration, to make room for new objects. Assuming the region_prefix specified in persistence.xml was myprefix, the default name of the cache region for the com.mycompany.entities.Account entity bean would be /myprefix/com/mycompany/entities/Account.
<bean name="..." class="org.jboss.cache.config.Configuration">
... ...
<property name="evictionConfig">
<bean class="org.jboss.cache.config.EvictionConfig">
<property name="wakeupInterval">5000</property>
<!-- Overall default -->
<property name="defaultEvictionRegionConfig">
<bean class="org.jboss.cache.config.EvictionRegionConfig">
<property name="regionName">/</property>
<property name="evictionAlgorithmConfig">
<bean class="org.jboss.cache.eviction.LRUAlgorithmConfig">
<!-- Evict LRU node once we have more than this number of nodes -->
<property name="maxNodes">10000</property>
<!-- And, evict any node that has not been accessed in this many seconds -->
<property name="timeToLiveSeconds">1000</property>
<!-- Do not evict a node that's been accessed within this many seconds.
Set this to a value greater than your max expected transaction length. -->
<property name="minTimeToLiveSeconds">120</property>
</bean>
</property>
</bean>
</property>
<property name="evictionRegionConfigs">
<list>
<bean class="org.jboss.cache.config.EvictionRegionConfig">
<property name="regionName">/myprefix/com/mycompany/entities/Account</property>
<property name="evictionAlgorithmConfig">
<bean class="org.jboss.cache.eviction.LRUAlgorithmConfig">
<property name="maxNodes">10000</property>
<property name="timeToLiveSeconds">5000</property>
<property name="minTimeToLiveSeconds">120</property>
</bean>
</property>
</bean>
... ...
</list>
</property>
</bean>
</property>
</bean>
defaultEvictionRegionConfig as defined above. The @Cache annotation exposes an optional attribute "region" that lets you specify the cache region where an entity is to be stored, rather than having it be automatically created from the fully-qualified class name of the entity class.
@Entity
@Cache(usage = CacheConcurrencyStrategy.TRANSACTIONAL, region = "Account")
public class Account implements Serializable
{
// ... ...
}
<bean name="..." class="org.jboss.cache.config.Configuration">
... ...
<property name="evictionConfig">
<bean class="org.jboss.cache.config.EvictionConfig">
<property name="wakeupInterval">5000</property>
<!-- Overall default -->
<property name="defaultEvictionRegionConfig">
<bean class="org.jboss.cache.config.EvictionRegionConfig">
<property name="regionName">/</property>
<property name="evictionAlgorithmConfig">
<bean class="org.jboss.cache.eviction.LRUAlgorithmConfig">
<property name="maxNodes">5000</property>
<property name="timeToLiveSeconds">1000</property>
<property name="minTimeToLiveSeconds">120</property>
</bean>
</property>
</bean>
</property>
<property name="evictionRegionConfigs">
<list>
<bean class="org.jboss.cache.config.EvictionRegionConfig">
<property name="regionName">/myprefix/Account</property>
<property name="evictionAlgorithmConfig">
<bean class="org.jboss.cache.eviction.LRUAlgorithmConfig">
<property name="maxNodes">10000</property>
<property name="timeToLiveSeconds">5000</property>
<property name="minTimeToLiveSeconds">120</property>
</bean>
</property>
</bean>
... ...
</list>
</property>
</bean>
</property>
</bean>
24.1.3. Query result caching
<property name="hibernate.cache.use_query_cache" value="true"/>
@Entity
@Cache(usage = CacheConcurrencyStrategy.TRANSACTIONAL, region = "Account")
@NamedQueries(
{
@NamedQuery(
name = "account.bybranch",
query = "select acct from Account as acct where acct.branch = ?1",
hints = { @QueryHint(name = "org.hibernate.cacheable", value = "true") }
)
})
public class Account implements Serializable
{
// ... ...
}
persistence.xml, you could, for example, create this sort of eviction handling:
<bean name="..." class="org.jboss.cache.config.Configuration">
... ...
<property name="evictionConfig">
<bean class="org.jboss.cache.config.EvictionConfig">
<property name="wakeupInterval">5000</property>
<!-- Overall default -->
<property name="defaultEvictionRegionConfig">
<bean class="org.jboss.cache.config.EvictionRegionConfig">
<property name="regionName">/</property>
<property name="evictionAlgorithmConfig">
<bean class="org.jboss.cache.eviction.LRUAlgorithmConfig">
<property name="maxNodes">5000</property>
<property name="timeToLiveSeconds">1000</property>
<property name="minTimeToLiveSeconds">120</property>
</bean>
</property>
</bean>
</property>
<property name="evictionRegionConfigs">
<list>
<bean class="org.jboss.cache.config.EvictionRegionConfig">
<property name="regionName">/myprefix/Account</property>
<property name="evictionAlgorithmConfig">
<bean class="org.jboss.cache.eviction.LRUAlgorithmConfig">
<property name="maxNodes">10000</property>
<property name="timeToLiveSeconds">5000</property>
<property name="minTimeToLiveSeconds">120</property>
</bean>
</property>
</bean>
<bean class="org.jboss.cache.config.EvictionRegionConfig">
<property name="regionName">/myprefix/org/hibernate/cache/StandardQueryCache</property>
<property name="evictionAlgorithmConfig">
<bean class="org.jboss.cache.eviction.LRUAlgorithmConfig">
<property name="maxNodes">100</property>
<property name="timeToLiveSeconds">600</property>
<property name="minTimeToLiveSeconds">120</property>
</bean>
</property>
</bean>
</list>
</property>
</bean>
</property>
</bean>
@Entity
@Cache(usage = CacheConcurrencyStrategy.TRANSACTIONAL, region = "Account")
@NamedQueries(
{
@NamedQuery(
name = "account.bybranch",
query = "select acct from Account as acct where acct.branch = ?1",
hints =
{
@QueryHint(name = "org.hibernate.cacheable", value = "true"),
@QueryHint(name = "org.hibernate.cacheRegion", value = "Queries")
}
)
})
public class Account implements Serializable
{
// ... ...
}
<bean name="..." class="org.jboss.cache.config.Configuration">
... ...
<property name="evictionConfig">
<bean class="org.jboss.cache.config.EvictionConfig">
<property name="wakeupInterval">5000</property>
<!-- Overall default -->
<property name="defaultEvictionRegionConfig">
<bean class="org.jboss.cache.config.EvictionRegionConfig">
<property name="regionName">/</property>
<property name="evictionAlgorithmConfig">
<bean class="org.jboss.cache.eviction.LRUAlgorithmConfig">
<property name="maxNodes">5000</property>
<property name="timeToLiveSeconds">1000</property>
<property name="minTimeToLiveSeconds">120</property>
</bean>
</property>
</bean>
</property>
<property name="evictionRegionConfigs">
<list>
<bean class="org.jboss.cache.config.EvictionRegionConfig">
<property name="regionName">/myprefix/Account</property>
<property name="evictionAlgorithmConfig">
<bean class="org.jboss.cache.eviction.LRUAlgorithmConfig">
<property name="maxNodes">10000</property>
<property name="timeToLiveSeconds">5000</property>
<property name="minTimeToLiveSeconds">120</property>
</bean>
</property>
</bean>
<bean class="org.jboss.cache.config.EvictionRegionConfig">
<property name="regionName">/myprefix/Queries</property>
<property name="evictionAlgorithmConfig">
<bean class="org.jboss.cache.eviction.LRUAlgorithmConfig">
<property name="maxNodes">100</property>
<property name="timeToLiveSeconds">600</property>
<property name="minTimeToLiveSeconds">120</property>
</bean>
</property>
</bean>
... ...
</list>
</property>
</bean>
</property>
</bean>

Where did the comment section go?
Red Hat's documentation publication system recently went through an upgrade to enable speedier, more mobile-friendly content. We decided to re-evaluate our commenting platform to ensure that it meets your expectations and serves as an optimal feedback mechanism. During this redesign, we invite your input on providing feedback on Red Hat documentation via the discussion platform.