Oct 9, 2009

Hibernate Caching

Introduction

Hibernate is a high-performance, object/relational persistence and query service, but it won't solve all the performance issues without a little help. Hence we use the concept of Caching here. Caching is mainly used for optimizing database applications and is designed to reduce the traffic between our application and the database by conserving data already loaded from database. This article will give you the overview of Hibernate Caching mechanisms.




Hibernate Caching

By implementing Caching, the application will work with the data in the cache most of the time. Whenever there is a request for data that is not cached, the database will be contacted. So obviously the access time and traffic will be reduced between the application and the database. Here the cache stores only the data related to current running application. In order to do that, the cache must be cleared time to time whenever the applications are changing.

Hibernate uses two different caches for objects: first-level cache and second-level cache

First-Level Cache

  • First Level cache is associated with session object.
  • Hibernate uses first level cache within a single transaction boundary and also uses this by default.
  • This is mainly used to reduce the number of SQL queries it needs to generate within a given transaction. For Example, if an object is modified several times within the same transaction, Hibernate will generate only one SQL UPDATE at the end, containing all the modifications.

Second-Level Cache

  • Second level cache always associates with the session factory Object.
  • It keeps loaded objects at the session factory level across the transaction boundaries.
  • These objects are available to the whole application, not just to the user running the query. This way, each time a query returns an object that is already loaded in the cache; one or more database transactions potentially are avoided.
  • The second-level cache holds on to the 'data' for all properties and associations (and collections if requested) for individual entities that are marked to be cached.

Query-Level Cache

  • It can be used if we need to cache actual query results, rather than just persistent objects.
  • It does not cache the state of the actual entities in the result set; it caches only identifier values and results of value type. So the query cache should always be used in conjunction with the second-level cache.

Caching Implementations

Hibernate comes with a number of built-in integrations with open-source cache providers. Each cache provides different capacities in terms of performance, memory use, and configuration possibilities. Some of them are listed below.

EHCache (Easy Hibernate Cache)

  • Ehcache is a widely used java distributed cache for general purpose caching, Java EE and light-weight containers.
  • Provider class : org.hibernate.cache.EhCacheProvider
  • It is a fast, lightweight, and easy-to-use in-process cache.
  • supports read-only and read/write caching and memory- and disk-based caching
  • It does not support clustering

OSCache (Open Symphony Cache)

  • OSCache is a caching solution that includes a JSP tag library and set of classes to perform fine grained dynamic caching of JSP content, servlet responses or arbitrary objects.
  • Provider class : org.hibernate.cache.OSCacheProvider
  • Provides caching functionalities for JSP pages or arbitrary objects.
  • Also supports read-only and read/write caching, and memory- and disk-based caching
  • Provides basic support for clustering via either Java Groups or JMS.

SwarmCache

  • SwarmCache is a simple cluster-based caching solution based on JavaGroups.
  • It uses IP multicast to efficiently communicate with any number of hosts on a LAN
  • Provider class: org.hibernate.cache.SwarmCacheProvider
  • Supports read-only or nonstrict read/write caching
  • It is specifically designed for use by clustered, database-driven web applications. Such applications typically have many more read operations than write operations, which allows SwarmCache to deliver the greatest performance gains

JBoss TreeCache

  • It provides enterprise-grade clustering solutions to Java-based frameworks, application servers or custom-designed Java SE applications.
  • Is a powerful replicated (synchronous or asynchronous) and transactional cache
  • Provider class: org.hibernate.cache.TreeCacheProvider
  • useful when we need a true transaction-capable caching architecture

Configuration

Configuration of a particular caching mechanism is specified in the hibernate.cfg.xml file as in the below example.

<hibernate-configuration>

<session-factory>

...

<property name="hibernate.cache.provider_class">

org.hibernate.cache.EHCacheProvider

</property>

...

</session-factory>

</hibernate-configuration>

The name in <property> tag must be hibernate.cache.provider_class for activating second-level cache. We can use hibernate.cache.use_second_level_cache property, which allows you to activate and deactivate the second-level cache. By default, the second-level cache is activated and uses the EHCache.


Caching Strategies

It is very important to select the specific Caching strategy after selecting the particular cache implementation. Because none of the cache providers support all of the cache concurrency strategies. The following four caching strategies are available:

  • Read-only: This strategy is useful for data that is read frequently but never updated. This is by far the simplest and best-performing cache strategy. Here is an example for using the read-only cache strategy.

<class name="abc.mutable” mutable="true ">

<cache usage="read-only"/>

....

</class>

  • Read/write: Read/write caches may be appropriate if your data needs to be updated. They carry more overhead than read-only caches. In non-JTA environments, each transaction should be completed when Session.close () or Session.disconnect () is called. Here is an example for using the read-write cache strategy.

<class name="abc.xyz" .... >

<cache usage="read-write"/>

….

<set name="yuv" ... >

<cache usage="read-write"/>

….

</set>

</class>

  • Nonstrict read/write: This strategy does not guarantee that two transactions won't simultaneously modify the same data. Therefore, it may be most appropriate for data that is read often but only occasionally modified. An example for NonStrict read-write cache strategy,

<class name="abc.xyz" .... >

<cache usage=" nonstrict-read-write"/>

……

</class>

  • Transactional: This is a fully transactional cache that may be used only in a JTA environment.

The caching strategy options available for different cache implementations are described in the following table.

Cache

Read-Only

NonStrict Read/ Write

Read/Write

Transactional

EHCache

Yes

Yes

Yes

No

OSCache

Yes

Yes

Yes

No

SwarmCache

Yes

Yes

No

No

JBoss TreeCache

Yes

No

No

Yes


Conclusion

Hibernate has a flexible and powerful way of implementing caching mechanisms which will be very helpful in improving the performance of web applications which incorporate heavy database traffics. It should be implemented using an incremental, test-driven approach. When done correctly, a small amount of well executed caching can boost our applications to their maximum capacities.


References

0 comments:

Text Widget

Copyright © Vinay's Blog | Powered by Blogger

Design by | Blogger Theme by