WebSphere eXtreme Scale Administration Guide > Configure WebSphere eXtreme Scale > Cache integration > JPA cache plug-in > JPA cache plug-in configuration



Hibernate cache plug-in configuration


An eXtreme Scale cache can be enabled for Hibernate by setting properties in the configuration file.

[v7.0 fix 4 or later] For integration with WebSphere Application Server, the hibernate cache plug-in is packaged in oghibernate-cache.jar and installed in WAS_HOME/optionalLibraries/ObjectGrid. To use the hibernate cache plug-in, you have to include the oghibernate-cache.jar in the hibernate library. For example, if you include the hibernate library in the application, you have to include the oghibernate-cache.jar file, too. If you define a shared library to include hibernate library, you have to put the oghibernate-cache.jar into the shared library directory.


Sets

The syntax for setting the property in the persistence.xml file follows:

persistence.xml

<property name="hibernate.cache.provider_class"
         value="com.ibm.websphere.objectgrid.hibernate.cache.ObjectGridHibernateCacheProvider" />
<property name="hibernate.cache.use_query_cache" value="true"/>
<property name="objectgrid.configuration" value="<property>=<value>,..." />
<property name="objectgrid.hibernate.regionNames" value="<regionName>,.." />

The syntax for setting the property in the hibernate.cfg.xml file follows:

hibernate.cfg.xml

<property name="cache.provider_class">com.ibm.websphere.objectgrid.
          hibernate.cache.ObjectGridHibernateCacheProvider</property>
<property name="cache.use_query_cache">true</property>
<property name="objectgrid.configuration"><property>=<value>,...</property>
<property name="objectgrid.hibernate.regionNames"><regionName>,...</property>

The provider_class property is the com.ibm.websphere.objectgrid.hibernate.cache.ObjectGridHibernateCacheProvider property.

To enable query cache, set the value to true on the use_query_cache property. Use the objectgrid.configuration property to specify eXtreme Scale cache configuration properties.

You must specify a unique ObjectGridName property value to avoid potential naming conflicts. The other eXtreme Scale cache configuration properties are optional.

The objectgrid.hibernate.regionNames property is optional and should be specified when the regionNames values are defined after the eXtreme Scale cache is initialized. Consider the example of an entity class that is mapped to a regionName with the entity class unspecified in the persistence.xml file or not included in the Hibernate mapping file. Further, say it does have Entity annotation. Then, the regionName for this entity class is resolved at class loading time when the eXtreme Scale cache is initialized. Another example is the Query.setCacheRegion(String regionName) method that runs after the eXtreme Scale cache initialization. In these situations, include all possible dynamic determined regionNames in the objectgrid.hibernate.regionNames property so that the eXtreme Scale cache can prepare BackingMaps for all regionNames.

The following are examples of the persistence.xml and hibernate.cfg.xml files:

persistence.xml

<persistence-unit name="testPU2">
   
<provider>org.hibernate.ejb.HibernatePersistence</provider>
   
<class>com.ibm.websphere.objectgrid.jpa.test.Department</class>
   
<properties>
     
<property name="hibernate.show_sql" value="true" />
     
<property name="hibernate.connection.url" value="jdbc:derby:DB_testPU2;create=true" />
     
<property name="hibernate.connection.driver_class" value="org.apache.derby.jdbc.EmbeddedDriver" />

     
<property name="hibernate.cache.provider_class" value="com.ibm.websphere.objectgrid.
               hibernate.cache.ObjectGridHibernateCacheProvider" />
     
<property name="hibernate.cache.use_query_cache" value="true"/>
     
<property name="objectgrid.configuration" value="ObjectGridName=myOGName,ObjectGridType=
               EMBEDDED,MaxNumberOfReplicas=4" writeBehind=true, writeBehindInterval=5000, 
               writeBehindPoolSize=10, writeBehindMaxBatchSize=1000" />
     
<property name="objectgrid.hibernate.regionNames" value="queryRegion1, queryRegion2" />
   
</properties>
</persistence-unit>

[v7.0 fix 4 or later] v7.0 Fix 4 introduces additional write behind function specific configuration options for the Hibernate cache plug-in, in addition to standard JPA cache plug-in configuration options.

writeBehind


Valid values: TRUE or FALSE


Default value: FALSE

When writeBehind is enabled, updates are temporarily stored in a JVM scope data storage until either the writeBehindInterval or writeBehindMaxBatchSize condition is met.

Attention: Unless writeBehind is enabled, the other write behind configuration settings are disregarded.

writeBehindInterval


Valid values: greater than or equal to 1


Default value: 5000 (5 seconds)

Specifies the time interval in milliseconds to flush updates to the cache.

writeBehindPoolSize


Valid values: greater than or equal to 1


Default value: 5

Specifies the maximum size of the thread pool used in flushing updates to the cache.

writeBehindMaxBatchSize


Valid values: greater than or equal to 1


Default value: 1000

Specifies the maximum batch size per region cache in flushing updates to the cache.

The preceding code example displays the following write behind function configuration:

writeBehind=true, writeBehindInterval=5000, writeBehindPoolSize=10, writeBehindMaxBatchSize=1000

where

Take care when using the write behind function configuration. It introduces longer latency of data synchronization across all JVMs and a higher chance of lost updates. In a system using write behind configuration with four or more JVMs, the update performed on one JVM will have an approximate 15 second delay before the update becomes available to other JVMs. If any two JVMs update the same entry, the one that flushes the update first will lose its update.

hibernate.cfg.xml

<hibernate-configuration>
   
<session-factory>
       
<!-- Database connection settings -->
       
<property name="connection.driver_class">org.apache.derby.jdbc.EmbeddedDriver</property>
       
<property name="connection.url">jdbc:derby:DB_testPU2;create=true</property>
       
<!-- ObjectGrid cache setting-->
       
<property name="cache.provider_class">com.ibm.websphere.objectgrid.hibernate.cache.
                 ObjectGridHibernateCacheProvider</property>
       
<property name="cache.use_query_cache">true</property>
       
<property name="objectgrid.configuration">ObjectGridName=myOGName,
                 ObjectGridType=EMBEDDED,MaxNumberOfReplicas=4
</property>
       
<property name="objectgrid.hibernate.regionNames">queryRegion1, queryRegion2</property>

       
<mapping resource="com/ibm/websphere/objectgrid/jpa/test/Employee.hbm.xml"/>

   
</session-factory>
</hibernate-configuration>


Preloading data into the ObjectGrid cache

You can use the preload method of the ObjectGridHibernateCacheProvider class to preload data into the ObjectGrid cache for an entity class.


Example 1


Use EntityManagerFactory

EntityManagerFactory emf = Persistence.createEntityManagerFactory("testPU");
ObjectGridHibernateCacheProvider.preload("objectGridName", emf, TargetEntity.class, 100, 100);

By default, entities are not part of the second level cache. In the Entity classes that need caching, the @cache annotation has to be added like the following:

import org.hibernate.annotations.Cache;
import org.hibernate.annotations.CacheConcurrencyStrategy;
@Entity
@Cache(usage=CacheConcurrencyStrategy.TRANSACTIONAL)
public class HibernateCacheTest { ... }

You can override this default by setting the shared-cache-mode element in the persistence.xml file or by using the javax.persistence.sharedCache.mode property.


Example 2


Use SessionFactory

org.hibernate.cfg.Configuration cfg = new Configuration();
// use addResource, addClass, and setProperty method of Configuration to prepare 
// configuration required to create SessionFactor
SessionFactory sessionFactory= cfg.buildSessionFactory();
ObjectGridHibernateCacheProvider.preload("objectGridName", sessionFactory, 
TargetEntity.class, 100, 100);

  1. In a distributed system, this preload mechanism can only be invoked from one Java™ virtual machine. The preload mechanism cannot run simultaneously from multiple Java virtual machines.

  2. Before running the preload, initialize the eXtreme Scale cache by creating EntityManager using EntityManagerFactory in order to have all corresponding BackingMaps created; otherwise, the preload forces the cache to be initialized with only one default BackingMap to support all entities. This means a single BackingMap is shared by all entities.


Customize Hibernate cache configuration with XML

For most scenarios, setting cache properties should be sufficient.

To further customize the ObjectGrid used by the cache, you can provide Hibernate ObjectGrid configuration XML files in the META-INF directory similarly to the persistence.xml file. During initialization, the cache will try to locate these XML files and process them if found.

There are three types of Hibernate ObjectGrid configuration XML files: hibernate-objectGrid.xml (ObjectGrid configuration), hibernate-objectGridDeployment.xml (deployment policy), and hibernate-objectGrid-client-override.xml (client ObjectGrid override configuration). Depending on the configured eXtreme Scale topology, you can provide any one of these three XML files to customize that topology.

For both the EMBEDDED and EMBEDDED_PARTITION type, you can provide any one of the three XML files to customize the ObjectGrid, deployment policy, and client ObjectGrid override configuration.

For a REMOTE ObjectGrid, the cache does not create a dynamic ObjectGrid. The cache only obtains a client-side ObjectGrid from the catalog service. You can only provide a hibernate-objectGrid-client-override.xml file to customize client ObjectGrid override configuration.

  1. ObjectGrid configuration: Use the META-INF/hibernate-objectGrid.xml file. This file is used to customize ObjectGrid configuration for both the EMBEDDED and EMBEDDED_PARTITION type. With the REMOTE type, this file is ignored. By default, each entity class has an associated regionName (default to entity class name) that is mapped to a BackingMap configuration named as regionName within the ObjectGrid configuration. For example, the com.mycompany.Employee entity class has an associated regionName default to com.mycompany.Employee BackingMap. The default BackingMap configuration is readOnly="false", copyKey="false", lockStrategy="NONE", and copyMode="NO_COPY". You can customize some BackingMaps with a chosen configuration. The reserved key word "ALL_ENTITY_MAPS" can be used to represent all maps excluding other customized maps listed in the hibernate-objectGrid.xmlfile. BackingMaps that are not listed in this hibernate-objectGrid.xml file use the default configuration.

  2. ObjectGridDeployment configuration: Use the META-INF/hibernate-objectGridDeployment.xml file. This file is used to customize deployment policy. When you are customizing deployment policy, if the hibernate-objectGridDeployment.xml is provided, the default deployment policy is discarded. All deployment policy attribute values will come from the provided hibernate-objectGridDeployment.xml file.

  3. Client override ObjectGrid configuration: Use the META-INF/hibernate-objectGrid-client-override.xml file . This file is used to customize a client-side ObjectGrid. By default, the ObjectGrid cache applies a default client override configuration that disables the near cache. If the application requires a near cache, it can provide this file and specify numberOfBuckets="xxx". The default client override disables the near cache by setting numberOfBuckets="0". The near cache can be active when resetting numberOfBuckets attribute to a value greater than 0 with the hibernate-objectGrid-client-override.xml file. The way that the hibernate-objectGrid-client-override.xml file works is similar to hibernate-objectGrid.xml: It overrides or extends the default client ObjectGrid override configuration.


Hibernate ObjectGrid XML file examples

Hibernate ObjectGrid XML files should be created based on the configuration of a persistence unit.

An example persistence.xml file that represents the configuration of a persistence unit follows:

persistence.xml

<persistence xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  version="1.0">
 
<persistence-unit name="AnnuityGrid">
   
<provider>org.hibernate.ejb.HibernatePersistence</provider>

   
<class>com.ibm.wssvt.acme.annuity.common.bean.jpa.AnnuityPersistebleObject</class>
   
<class>com.ibm.wssvt.acme.annuity.common.bean.jpa.Annuity</class>
   
<class>com.ibm.wssvt.acme.annuity.common.bean.jpa.FixedAnnuity</class>
   
<class>com.ibm.wssvt.acme.annuity.common.bean.jpa.EquityAnnuity</class>
   
<class>com.ibm.wssvt.acme.annuity.common.bean.jpa.Payout</class>
   
<class>com.ibm.wssvt.acme.annuity.common.bean.jpa.Rider</class>
   
<class>com.ibm.wssvt.acme.annuity.common.bean.jpa.Payor</class>
   
<class>com.ibm.wssvt.acme.annuity.common.bean.jpa.Person</class>
   
<class>com.ibm.wssvt.acme.annuity.common.bean.jpa.AnnuityHolder</class>
   
<class>com.ibm.wssvt.acme.annuity.common.bean.jpa.Contact</class>
   
<class>com.ibm.wssvt.acme.annuity.common.bean.jpa.Address</class>

   
<exclude-unlisted-classes>true</exclude-unlisted-classes>

   
<properties>
     
<property name="hibernate.show_sql" value="false" />
     
<property name="hibernate.connection.url" value="jdbc:db2:Annuity" />
     
<property name="hibernate.connection.driver_class" value="com.ibm.db2.jcc.DB2Driver" />
     
<property name="hibernate.default_schema" value="EJB30" />

     
<!-- Cache -->
     
<property name="hibernate.cache.provider_class"
        value="com.ibm.websphere.objectgrid.hibernate.cache.ObjectGridHibernateCacheProvider" />
     
<property name="hibernate.cache.use_query_cache" value="true" />
     
<property name="objectgrid.configuration" value="ObjectGridType=EMBEDDED,
               ObjectGridName=Annuity, MaxNumberOfReplicas=4" />
   
</properties>
 
</persistence-unit>

</persistence>

The following is the hibernate-objectGrid.xml file that matches the persistence.xml file:

hibernate-objectGrid.xml

<?xml version="1.0" encoding="UTF-8"?>
<objectGridConfig xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://ibm.com/ws/objectgrid/config ../objectGrid.xsd"
  xmlns="http://ibm.com/ws/objectgrid/config">
 
<objectGrids>
   
<objectGrid name="Annuity">
     
<backingMap name="com.ibm.wssvt.acme.annuity.common.bean.jpa.Annuity" readOnly="false" copyKey="false"
                  lockStrategy="NONE" copyMode="NO_COPY" evictionTriggers="MEMORY_USAGE_THRESHOLD"
                  pluginCollectionRef="com.ibm.wssvt.acme.annuity.common.bean.jpa.Annuity" />
     
<backingMap name="defaultCacheMap" readOnly="false" copyKey="false"
                  lockStrategy="NONE" copyMode="NO_COPY" evictionTriggers="MEMORY_USAGE_THRESHOLD"
                  pluginCollectionRef="defaultCacheMap" />
     
<backingMap name="com.ibm.wssvt.acme.annuity.common.bean.jpa.Payor" readOnly="false" copyKey="false"
                  lockStrategy="NONE" copyMode="NO_COPY" evictionTriggers="MEMORY_USAGE_THRESHOLD"
                  pluginCollectionRef="com.ibm.wssvt.acme.annuity.common.bean.jpa.Payor" />
     
<backingMap name="com.ibm.wssvt.acme.annuity.common.bean.jpa.Contact" readOnly="false" copyKey="false"
                  lockStrategy="NONE" copyMode="NO_COPY" evictionTriggers="MEMORY_USAGE_THRESHOLD"
                  pluginCollectionRef="com.ibm.wssvt.acme.annuity.common.bean.jpa.Contact" />
     
<backingMap name="com.ibm.wssvt.acme.annuity.common.bean.jpa.Person" readOnly="false" copyKey="false"
                  lockStrategy="NONE" copyMode="NO_COPY" evictionTriggers="MEMORY_USAGE_THRESHOLD"
                  pluginCollectionRef="com.ibm.wssvt.acme.annuity.common.bean.jpa.Person" />
     
<backingMap name="com.ibm.wssvt.acme.annuity.common.bean.jpa.Rider" readOnly="false" copyKey="false"
                  lockStrategy="NONE" copyMode="NO_COPY" evictionTriggers="MEMORY_USAGE_THRESHOLD"
                  pluginCollectionRef="com.ibm.wssvt.acme.annuity.common.bean.jpa.Rider" />
     
<backingMap name="com.ibm.wssvt.acme.annuity.common.bean.jpa.Payout" readOnly="false" copyKey="false"
                  lockStrategy="NONE" copyMode="NO_COPY" evictionTriggers="MEMORY_USAGE_THRESHOLD"
                  pluginCollectionRef="com.ibm.wssvt.acme.annuity.common.bean.jpa.Payout" />
     
<backingMap name="org.hibernate.cache.UpdateTimestampsCache" readOnly="false" copyKey="false"
                  lockStrategy="NONE" copyMode="NO_COPY" evictionTriggers="MEMORY_USAGE_THRESHOLD"
                  pluginCollectionRef="org.hibernate.cache.UpdateTimestampsCache" />
     
<backingMap name="org.hibernate.cache.StandardQueryCache" readOnly="false" copyKey="false"
                  lockStrategy="NONE" copyMode="NO_COPY" evictionTriggers="MEMORY_USAGE_THRESHOLD"
                  pluginCollectionRef="org.hibernate.cache.StandardQueryCache" />
   
</objectGrid>
 
</objectGrids>
 
<backingMapPluginCollections>
   
<backingMapPluginCollection id="com.ibm.wssvt.acme.annuity.common.bean.jpa.Annuity">
     
<bean id="Evictor" className="com.ibm.websphere.objectgrid.plugins.builtins.LRUEvictor" >
     
</bean>
   
</backingMapPluginCollection>
   
<backingMapPluginCollection id="defaultCacheMap">
     
<bean id="Evictor" className="com.ibm.websphere.objectgrid.plugins.builtins.LRUEvictor" >
     
</bean>
   
</backingMapPluginCollection>
   
<backingMapPluginCollection id="com.ibm.wssvt.acme.annuity.common.bean.jpa.Payor">
     
<bean id="Evictor" className="com.ibm.websphere.objectgrid.plugins.builtins.LRUEvictor" >
     
</bean>
   
</backingMapPluginCollection>
   
<backingMapPluginCollection id="com.ibm.wssvt.acme.annuity.common.bean.jpa.Contact">
     
<bean id="Evictor" className="com.ibm.websphere.objectgrid.plugins.builtins.LRUEvictor" >
     
</bean>
   
</backingMapPluginCollection>
   
<backingMapPluginCollection id="com.ibm.wssvt.acme.annuity.common.bean.jpa.Person">
     
<bean id="Evictor" className="com.ibm.websphere.objectgrid.plugins.builtins.LRUEvictor" >
     
</bean>
   
</backingMapPluginCollection>
   
<backingMapPluginCollection id="com.ibm.wssvt.acme.annuity.common.bean.jpa.Rider">
     
<bean id="Evictor" className="com.ibm.websphere.objectgrid.plugins.builtins.LRUEvictor" >
     
</bean>
   
</backingMapPluginCollection>
   
<backingMapPluginCollection id="com.ibm.wssvt.acme.annuity.common.bean.jpa.Payout">
     
<bean id="Evictor" className="com.ibm.websphere.objectgrid.plugins.builtins.LRUEvictor" >
     
</bean>
   
</backingMapPluginCollection>
   
<backingMapPluginCollection id="org.hibernate.cache.UpdateTimestampsCache">
     
<bean id="Evictor" className="com.ibm.websphere.objectgrid.plugins.builtins.LRUEvictor" >
     
</bean>
   
</backingMapPluginCollection>
   
<backingMapPluginCollection id="org.hibernate.cache.StandardQueryCache">
     
<bean id="Evictor" className="com.ibm.websphere.objectgrid.plugins.builtins.LRUEvictor" >
     
</bean>
   
</backingMapPluginCollection>
 
</backingMapPluginCollections>
</objectGridConfig>

The org.hibernate.cache.UpdateTimestampsCache, org.hibernate.cache.StandardQueryCache and defaultCacheMap maps are required.

The hibernate-objectGridDeployment.xml file that matches the persistence.xml follows:

hibernate-objectGridDeployment.xml

<?xml version="1.0" encoding="UTF-8" ?>
<deploymentPolicy xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://ibm.com/ws/objectgrid/deploymentPolicy ../deploymentPolicy.xsd"
  xmlns="http://ibm.com/ws/objectgrid/deploymentPolicy">
 
<objectgridDeployment objectgridName="Annuity">
   
<mapSet name="MAPSET_Annuity" numberOfPartitions="1" numInitialContainers="1" minSyncReplicas="0"
           maxSyncReplicas="4" maxAsyncReplicas="0" replicaReadEnabled="true">
     
<map ref="com.ibm.wssvt.acme.annuity.common.bean.jpa.Annuity" />
     
<map ref="defaultCacheMap" />
     
<map ref="com.ibm.wssvt.acme.annuity.common.bean.jpa.Payor" />
     
<map ref="com.ibm.wssvt.acme.annuity.common.bean.jpa.Contact" />
     
<map ref="com.ibm.wssvt.acme.annuity.common.bean.jpa.Person" />
     
<map ref="com.ibm.wssvt.acme.annuity.common.bean.jpa.Rider" />
     
<map ref="com.ibm.wssvt.acme.annuity.common.bean.jpa.Payout" />
     
<map ref="org.hibernate.cache.UpdateTimestampsCache" />
     
<map ref="org.hibernate.cache.StandardQueryCache" />
   
</mapSet>
 
</objectgridDeployment>
</deploymentPolicy>

The org.hibernate.cache.UpdateTimestampsCache, org.hibernate.cache.StandardQueryCache and defaultCacheMap maps are required.


External system for a cache with REMOTE ObjectGrid type

You must set up an external eXtreme Scale system if to configure a cache with a REMOTE ObjectGrid type. You need both ObjectGrid and ObjectGridDeployment configuration XML files that are based on the persistence.xml file to set up an external system. The Hibernate ObjectGrid and ObjectGridDeployment configuration XML files that are described in the Hibernate ObjectGrid XML files example section can also be used to setup an external eXtreme Scale system.

An external ObjectGrid system has both catalog service and ObjectGrid server processes. You must start a catalog service before starting container servers. See Start stand-alone WebSphere eXtreme Scale servers and Start container processes for more information.


Troubleshoot

  1. CacheException: Failed to get ObjectGrid server

    With either an EMBEDDED or EMBEDDED_PARTITION ObjectGridType, the cache tries to obtain a server instance from the eXtreme Scale runtime. In a Java Platform, Standard Edition environment, an eXtreme Scale server with embedded catalog service will be started. The embedded catalog service tries to listen to port 2809; if that port is being used by another process, this error occurs. If external catalog service endpoints are specified, for instance, with the objectGridServer.properties file, this error occurs if the host name or port is specified incorrectly.

  2. CacheException: Failed to get REMOTE ObjectGrid for configured REMOTE ObjectGrid. objectGridName = [ObjectGridName], PU name = [persistenceUnitName]

    This error occurs when the cache fails to obtain an ObjectGrid from the provided catalog service end points. Typically, the error is because of an incorrect host name or port.

  3. CacheException: Cannot have two PUs [persistenceUnitName_1, persistenceUnitName_2] configured with same ObjectGridName [ObjectGridName] of EMBEDDED ObjectGridType

    This exception occurs if you have a configuration with many persistence units and the caches of these units are configured with the same ObjectGrid name and EMBEDDED ObjectGridType. These persistence unit configurations coan be in the same or different persistence.xml files. You must verify that the ObjectGrid name is unique for each persistence unit when ObjectGridType is EMBEDDED.

  4. CacheException: REMOTE ObjectGrid [ObjectGridName] does not include required BackingMaps [mapName_1, mapName_2,...]

    With a REMOTE ObjectGrid type, if the obtained client-side ObjectGrid does not have complete entity BackingMaps to support the cache for the persistence unit, this exception results. For example, five entity classes are listed in the configuration for the persistence unit, but the obtained ObjectGrid only has two BackingMaps. Even though the obtained ObjectGrid might have ten BackingMaps, if any one of the five required entity BackingMaps are not found in the ten BackingMaps, this exception still occurs.



Parent topic

JPA cache plug-in configuration


+

Search Tips   |   Advanced Search