Tuesday, November 26, 2013

Hibernate Performance Tuning

06.10.2009
 | 75839 views | 
Hibernate is a powerful, high performance object/relational persistence and query service. Hibernate lets you develop persistent classes following object-oriented idiom - including association, inheritance, polymorphism, composition, and collections. Hibernate allows you to express queries in its own portable SQL extension (HQL), as well as in native SQL, or with an object-oriented Criteria and Example API.
Quintessential to using any ORM framework like hibernate is to know how to leverage the various performance tuning methods supported by the framework.
In this volume Wings Jiang discusses three performance tuning strategies for hibernate:
  1. SQL Optimization
  2. Session Management
  3. Data Caching

 

SQL Optimization

When using Hibernate in your application, you already have been coding HQL (Hibernate Query Language) somewhere. For example, “from User user where user.name = ‘John’”. If issuing your SQL statement like this, Hibernate cannot use the SQL cache implemented by database because name of the user, in most scenarios, is extremely distinct. On the contrary, while using placeholder to achieve this, like “from User user where user.name =?” will be cached by the Database to fulfill the performance improvement. You can also set some Hibernate properties to improve performance, such as setting the number of records retrieved while fetching records via configuring propertyhibernate.jdbc.fetch_size, setting the batch size when committing the batch processing via configuring property hibernate.jdbc.batch_size and switching off the SQL output via setting propertyhibernate.show_sql to false in product environments. In addition, the performance tuning of your target Database is also significant, like SQL clauses tuning, reasonable indexes, delicate table structures, data partitions etc.

Session Management

Undoubtedly, Session is the pith of Hibernate. It manages the Database related attributes, such as JDBC connections, data entities’ states. Managing the Session efficiently is the key to getting high performance in enterprise applications. One of the many commonly used and equally elegant approaches to session management in hibernate is to use ThreadLocal. Threadlocal will create a local copy of session for every thread. Thus synchronization problems are averted, when objects are put in the Threadlocal, . To understand how ThreadLocal variables are used in Java, refer to Sun Java Documentation at http://java.sun.com/j2se/1.5.0/docs/api/java/lang/ThreadLocal.html

Data Caching

Before accomplishing any data caching, it is essential to set the propertyhibernate.cache.user_query_cache = true.
There are three kinds of commonly used Caching Strategies in Hibernate:
Using cache based on Session level (aka Transaction layer level cache). This is also called first-level cache.

Using cache based on SessionFactory level (Application layer level cache). This is also called second-level cache.

Using cluster cache which is employed in distributed application (in different JVMs). In fact, some techniques, like loading data by id, lazy initialization which betokens loading appropriate data in proper time rather than obtaining a titanic number of  useless records, which are fairly useless in the subsequent operations are consummated via data caching.

First Level Cache (aka Transaction layer level cache)
Fetching an object from database always has a cost associated with it. This can be offset by storing the entities in hibernate session. Next time the entities are required, they are fetched from the session, rather than fetching from the database.

To clear an object from the session use: session.evict(object). To clear all the objects from the session use session.clear().
Second Level Cache (aka Application layer level cache)
 
In this approach, if an object is not found in session, it is searched for in the session factory before querying the database for the object.
If an object is indeed fetched from database, the selected data should be put in session cache. This would improve the performance when the object is required next time. To remove an entity from session factory use the various overloaded implementations of evict() method of SessionFactory.

In fact, Hibernate lets you tailor your own caching implementation by specifying the name of a class that implements org.hibernate.cache.CacheProvider using the propertyhibernate.cache.provider_class. But it is recommended to employ a few built-in integrations with open source cache providers (listed below).
 
In order to use second level caching, developers have to append some configurations inhibernate.cfg.xml (for example, using EHCache here).
1.<hibernate-configuration>
2.<session-factory>
3.<property name="hibernate.cache.provider_class">
4.net.sf.ehcache.hibernate.Provider
5.</property>
6.</session-factory>
7.</hibernate-configuration>
In addition, developers also need to create a cache specific configuration file (Example: ehcache.xmlfor EHCache).
01.<ehcache>
02.<diskStore path="java.io.tmpdir"/>       (1)
03.<defaultCache
04.maxElementsInMemory="10000"             (2)
05.eternal="false"                      (3)
06.timeToIdleSeconds="120"              (4)
07.timeToLiveSeconds="120"              (5)
08.overflowToDisk="true"                 (6)
09./>
10.</ehcache>
  1. diskStore : Sets the path to the directory where cache .data files are created. The following properties are translated:
    a.user.home - User's home directory
    b.user.dir - User's current working directory
    c.java.io.tmpdir (Default temp file path)
  2. maxElementsInMemory : Sets the maximum number of objects that will be created in memory.
  3. eternal : Sets whether elements are eternal. If eternal,  timeouts are ignored and the element is never expired.
  4. timeToIdleSeconds : Sets the time to idle for an element before it expires. Is only used if the element is not eternal. Idle time is now - last accessed time.
  5. timeToLiveSeconds : Sets the time to live for an element before it expires. Is only used if the element is not eternal. TTL is now - creation time
  6. overflowToDisk : Sets whether elements can overflow to disk when the in-memory cache has reached the maxInMemory limit.
Finally the cache concurrency strategy has to be specified in mapping files. For example, the following code fragment shows how to configure your cache strategy.
1.<class name="org.jmatrix.user.User" table="USER">
2.<cache usage=”read-write” />
3.
4.<set name="address" … >
5.<cache usage="read-only" />
6.</set>
7.
8.</class>
Legacy
Published at DZone with permission of its author, Ming Jiang.

No comments: