Access Keys:
Skip to content (Access Key - 0)
(Access Key - l)
Update Coming

This document is not up-to-date with Terracotta 3.0. Note the following:

  • EHCache 1.2.4 is no longer supported.
  • EHCache 1.3 and 1.4.1 are supported.
  • Hibernate 3.1.2 is no longer supported.
  • Hibernate 3.2.x is supported.
  • If you are using Terracotta 2.x, we strongly recommend upgrading to Terracotta 3.0.

This document will be updated shortly.

Configuring Hibernate to Work with Terracotta

Overview

This guide shows how to implement a simple configuration scheme to integrate Hibernate with Terracotta using either (or both) of two Hibernate modes. It assumes you already have an application written with Hibernate.

If you are new to Terracotta, the following introductory resources are recommended:

Watch the Webcast

To learn how Terracotta can help you with a Hibernate-enabled application, visit the webcasts page and select the Hibernate webcast to see:

  • How Terracotta helps Hibernate applications
  • A demonstration application in action
  • How to enable second-level object and query caching
  • How to enable detached mode with Terracotta for even better performance

You can also browse the source code discussed in the webcast:

Requirements

Terracotta for Hibernate requires the following:

  • Latest version of Terracotta
  • The latest released Hibernate Terracotta Integration Module (TIM):
    • Terracotta 2.7 and above: Download and install the TIM through the TIM Update Center.
      This is the easiest and most efficient way to download TIMs.
    • Terracotta 2.6 and older: Download and install the latest released Hibernate TIM or snapshot TIM for your version of Terracotta.
  • The latest released CGLIB TIM:
    • Terracotta 2.7 and above: Download and install the TIM through the TIM Update Center.
      This is the easiest and most efficient way to download TIMs.
    • Terracotta 2.6 and older: Download and install the latest released CGLIB TIM or snapshot TIM for your version of Terracotta.
  • Supported Platform such as Microsoft Windows, Linux, or Solaris
  • Supported JVM such as Sun Hotspot 1.4, 1.5, or 1.6 and/or IBM JDK 1.5
  • Hibernate Version 3.1.2 or 3.2.5
    (or visit the Hibernate home page)
  • An application enabled with Hibernate

Additional Requirements for Second-Level Cache Setup

If you plan to use Terracotta and Hibernate with EHCache as a second-level cache, you must also install the following:

To determine which version of Hibernate, EHCache, and TIMs go together, see the following table, in which each row represents an integration solution.

Integration Solution Hibernate version EHCache version TIMs
1 Hibernate 3.1.2 EHCache 1.2.4 tim-hiberate-3.1.2
tim-ehcache-1.2.4
cglib-2.1.3
2 Hibernate 3.2.5 EHCache 1.3 tim-hiberate-3.2.5
tim-ehcache-1.3
cglib-2.1.3

The version shown in the TIM column refers to the target application, not the TIM version. Always use the latest TIMs for your version of Terracotta.

Installing Terracotta

To install Terracotta, follow these steps:
  • Download Terracotta.
  • For Windows, execute the installer.
    By default, Terracotta is installed in C:\Program Files\Terracotta\<Terracotta Version>
  • For all other platforms, untar/unzip the downloaded file to a home directory of your choice.

This document refers to the Terracotta installation directory as $TC_HOME.

Using Second-Level Cache or Detached Instances Mode

There are two Hibernate modes where Terracotta can help your application:

  • Second-Level Cache - Terracotta adds high performance and data replication.
  • Detached Instances (Detached Mode Objects) - Terracotta provides scale and high availability.

These modes are not mutually exclusive and can be used concurrently. They are explored in the following sections.

Second-Level Cache

Hibernate offers a second-level cache option, which can improve the performance of your Hibernate application by eliminating the need to fetch often-used data objects from the database. Instead, that data is stored, or cached, in process with your application.

Second-level caching strategy is explained in more detail on the Hibernate.org website: Performance Tuning.

In a scaled-out application, where more than one node in the cluster is using a second-level cache, data freshness may be difficult to maintain. Without any mechanism to provide replication of the underlying cache, data written in one node can be stale on a second node. Because the second node has no way of knowing that the database data has changed (due to a change made by the first node), the data returned by the second node can be stale or out of date.

This problem is not solved by Hibernate. It is up to the underlying cache to provide a replication scheme to keep multiple copies coherent. Terracotta provides a consistent mechanism to keep any cache written in Java synchronized, and therefore provides this support for caches such as EHCache.

In all distributed-caching use cases, using Terracotta — instead of the native clustering or replication mode provided by the underlying second-level cache technology — adds a number of important advantages:

  • Performance – Reading and writing to replicated data with Terracotta can be 10x – 100x faster than other solutions.
  • Reliability – Terracotta provides a parallel path to disk, meaning the data is simultaneously durable and persistent.
  • Scalability – Because Terracotta does not use Serialization for data transfer, its use of the network and memory subsystem in Java is significantly more efficient, and therefore offers much more scalability than traditional solutions.
  • Virtual Heap – Terracotta provides an automatic virtual heap, which allows the distributed cache to provide a significantly larger data size than can be provided by a single JVM. For large datasets, this is especially important as it allows the cache to adapt to the "hotset" of the data in the cache.
  • Cluster-wide load – Replication of data eliminates the need for more than one node to load data from the database. In a scaled-out application, this can reduce database load by a significant factor because only one node needs to request the data to satisfy a cache miss, and then any subsequent requests on other nodes for the same data result in cache hits.

Detached Instance Object Caching

Hibernate supports the notion of "detached instances". Detached instances are POJOs retrieved from an active session that have been detached from that session, and thus can live past the lifetime of the session. As detached instances they behave just like normal POJOs - until reconnected to a new session. When reconnected to the new session, any changes to the POJO state made while disconnected are "merged" back into the session, and flushed to the database when the session is committed.

Using detached instances can provide a significant performance improvement. Instead of having to query a database, the application has direct access to the data it needs, eliminating latency and improving throughput. In essence, detached instances provide your application with memory-speed read and writes. The Hibernate documentation states that using detached instances "enables a programming model for long running units of work that require user think-time. We call them application transactions, i.e. a unit of work from the point of view of the user."

The drawback to using detached instances is that any changes written to the instance are by definition not persisted to the database. In a scaled-out application, a failure of the system hosting the detached instance could mean loss of data.

However, using Terracotta to replicate detached instances, it is possible to:

  • gain the speed and throughput of in-memory read speed;
  • gain nearly in-memory write speed;
  • ensure that instance data is highly available;
  • ensure that instance data is fail-safe (not susceptible to loss in the event of a system failure).

Managing detached instances is no more complicated than managing POJOs. Any design technique using Terracotta and POJOs is applicable to Hibernate detached instances. Common methods of making Hibernate detached instances persistent are:

How to Configure Terracotta for Second-Level Caching

To enable Terracotta second-level cache integration, you must use EHCache as a second-level cache for Hibernate, then configure Terracotta for Hibernate and for EHCache. The steps are:

  • Step 1: Create an EHCache configuration
  • Step 2: Configure Hibernate for Second-Level Cache
  • Step 3: Configure Terracotta for Hibernate and EHCache

If you already have EHCache enabled as a second-level cache, skip Steps 1 and 2.

Step 1: Create an EHCache configuration

First, you must create an EHCache configuration. The details are available at the EHCache website under "Hibernate Caching".

The following is a basic EHCache configuration file that can help you get started:

<ehcache>
   <diskStore path="java.io.tmpdir"/>
   <defaultCache
       maxElementsInMemory="10000"
       eternal="false"
       overflowToDisk="false"
       timeToIdleSeconds="300"
       timeToLiveSeconds="300"
       diskPersistent="false"
       diskExpiryThreadIntervalSeconds="120"
       memoryStoreEvictionPolicy="LRU"/>

    <cache name="..." ... />
</ehcache>

You must specify a cache name in the <cache/> element's name attribute.

Step 2: Configure Hibernate for Second-Level Cache

Enable EHCache as a second-level cache for Hibernate by modifying your hibernate.xml file. The details are available at the Hibernate website.

The following is a set of recommended configuration settings for hibernate.xml:

<property name="hibernate.cache.use_second_level_cache">true</property>
<property name="hibernate.cache.use_query_cache">true</property>
<property name="cache.provider_class">org.hibernate.cache.EhCacheProvider</property>

These settings enable second-level caching, and also query caching.

Step 3: Configure Terracotta for Hibernate and EHCache

The TIMs you downloaded must be enabled in the Terracotta configuration file, tc-config.xml:

<clients>
  <modules>
    <module name="tim-hibernate-3.1.2" version="1.1.2"/>
    <module name="tim-ehcache-1.2.4" version="1.1.2"/>
  </modules>
</clients>

This configuration uses sample versions. If, for example, you are using Hibernate 3.2.5 and EHCache version 1.3, then use tim-hibernate-3.2.5 and tim-ehcache-1.3. The <module> element's version attribute, which refers to the TIM version, will also be different.

How to Configure Terracotta for Hibernate Detached Instances

Terracotta can share Hibernate detached instances just as it does standard POJOs. However, certain issues may arise if Terracotta attempts to share detached objects as is. These issues may be caused by the following:

  • Knowledge of which objects are detached and which are still managed (or still associated with a session) is not guaranteed. Detachment is a function of the application or application container.
  • Detached instances refer to local database-related resources but do not contain the session-state data expected by remote nodes. By definition, the original session associated with these instances has been closed, leaving behind references specific to the Hibernate ORM.
  • Threads on a local JVM may assume that the session-state data present in local detached instances is associated with the thread-specific session when in fact it is not. This is due to the Hibernate requirement that threads must be bound to a specific session.

The specific problems that can arise from these issues are often unpredictable because Hibernate (and JPA) explicitly forbid having multiple threads interact with detached objects.

The Terracotta Pojoizer utility solves these issues by allowing you to detach specified Hibernate object graphs. Furthermore, Pojoizer replaces the Hibernate collections in these detached instances with standard Java collections. Objects detached with Pojoizer can then be safely shared with Terracotta.

Pojoizer can also be used to build a much more efficient alternative to the standard implementation of a Hibernate L2 cache. By allowing you to cache standard POJOs instead of Hibernate blobs, Pojoizer removes the requirement for serialization/deserialization. This alternative can use EHCache, or take a simpler approach by using a concurrent collection such as ConcurrentHashMap or ConcurrentStringMap.

Procedure

Follow these steps to correctly enable Terracotta for detached instances:

Step 1: Download and install Terracotta Pojoizer.

Get download and installation instructions for Pojoizer from the Terracotta Forge. The Forge contains instructions on how to download, install, and use Pojoizer in your code to specify and detach target instances.

Whether you choose to use or not to use Pojoizer with Terracotta and Hibernate, be sure to perform extensive testing on your clustered application to discover issues such as unforeseen failure points or unwanted faulting patterns.

Be sure to also add the Pojoizer JAR to your classpath.

Step 2: Add calls to Pojoizer.

In your application code, add calls to Pojoizer to detach those objects you want Terracotta to share. For example:

import org.terracotta.pojoizer.Pojoizer;

User user = ... // load from Hibernate
user = Pojoizer.pojoize(user);  // use the returned object

Step 3: Consider missing data due to lazy loading.

Any object that is going to be detached by Pojoizer should have its entire state loaded before Pojoizer is called. Unless it is known that an object will never need the lazily loaded data, this requirement exists because Pojoizer removes the object's ability to lazily load data.

You can solve the lazy-loading issue in one of two ways:

  • Use Hibernate annotations to turn off lazy loading. See the Hibernate documentation for more information.
  • Use calls that force lazy loading for objects that will be detached with Pojoizer.

    Forcing lazy loading should be carefully tested because it may cause extremely large object graphs to load.

Step 4: Configure Terracotta for Hibernate.

Enable the Hibernate TIM in the Terracotta configuration file. For example:

<clients>
  <modules>
    <module name="tim-hibernate-3.1.2" version="1.1.2"/>
  </modules>
</clients>

Use TIM Update Center the latest TIM available for your versions of Terracotta and Hibernate. See Requirements for more information.

Step 5: Instrument Classes and create roots.

You can instrument the classes of the objects detached with Pojoizer just as you instrument the class of any POJO. You can also declare these objects as Terracotta roots.

No special code changes are needed for writebacks to the database, which is handled by your application and Hibernate as usual.

Step 6: Test the cluster.

Test your clustered application to confirm that detached instances are:

  • replicated and shared without error;
  • safe from system failures;
  • are being reattached by your application as it becomes necessary to commit them;
  • committed to the database as and when required;
  • committed with any changes that were made to their data while detached.

More Help

More information on how Terracotta and Hibernate work together is available. Some resources require a Terracotta account. Use the Sign In menu above to log in or create a new account.

For more information on integrations and TIMs, see the following resources:

Adaptavist Theme Builder (3.2.0) Powered by Atlassian Confluence 2.8.2, the Enterprise Wiki.
Free theme builder license