Administration guide > Configure the deployment environment > Configuring cache integration > JPA cache configuration properties
Hibernate cache plug-in configuration
An eXtreme Scale cache can be enabled for Hibernate by setting properties in the configuration file.
For integration with WebSphere Application Server, the hibernate cache plug-in is packaged in oghibernate-cache.jar and installed in was_root/optionalLibraries/ObjectGrid. To use the hibernate cache plug-in, you have to include the oghibernate-cache.jar file 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 file into the shared library directory.
eXtreme Scale, v7.1, does not install the cglib.jar file in the WebSphere Application Server environment. If you have existing applications or shared libraries, such as hibernate, which depend on the cglib.jar, locate cglib.jar and include it in the classpath. For example, if the application includes all hibernate library JAR files, but excludes the cglib.jar available with hibernate, include the cglib.jar comes from hibernate in the application.
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.1 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: FALSEWhen 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: 5Specifies 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: 1000Specifies 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=1000where
- writeBehind=TRUE enables the write behind function
- writeBehindInterval=5000 means that updates will flush to the cache approximately every 5 seconds
- writeBehindPoolSize=10 indicates that the maximum number of threads used to perform the work is 10 threads, when flushing updates to the cache
- writeBehindMaxBatchSize=1000 means that if the updates stored in the write behind storage of a region cache exceeds 1000 entries, the updates will be flushed to the cache, even the specified writeBehindInterval condition is not met. In other words, updates will flush to cache either approximately every 5 seconds or whenever the size of write behind storage of each region cache exceeds 1000 entries. Note, in the case of the writeBehindMaxBatchSize condition met; only the region cache that meets this condition will flush its updates in write behind storage to cache. A region cache usually is corresponding to an entity or a query.
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, add the @cache annotation. An example follows:
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);
- 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.
- 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.
- 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.
- 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.
- 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 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
- 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.
- 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.
- 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.
- 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 configuration properties
Related concepts
OpenJPA cache plug-in configuration