0

October 17

improving performance in hibernate

Posted by Ajay

For the last few months I have been looking at performance improvements for my application on multiple ends. One is at the GIS end and the other is of course the database end. CachingĀ  is a great way to provide the performance improvement. Caching on the GIS end was an interesting exercise I implemented, which is a story for another day.

Today let me pen my thoughts on improving performance at the Hibernate level. Hibernate has many performance improvement techniques, of course we have implemented a small sub set of that for our task. Let me first talk about Hibernate’s performance improvement strategies. If you want to take it all in at a glance, take a look at this mind map image (maybe click on it to enlarge it)

First we need to understand that

  • Sessionfactory is an immutable thread safe factory that initalize JDBC connections, connection pools and create Sessions.
  • Session is a non thread safe single unit of work that represents a transaction

Caching, a blessing in disguise

Caching reduces traffic between the database and application by conserving data that has already been loaded into the application. Caches store data that was already fetched so that multiple accesses on the same data takes lesser time. Essentially caching reduces disk access, reduces computation time and speeds up response to users.

Hibernate uses three levels of caching.

  • Level 1 mainly caches at the Session level
  • Level 2 cache does it as the SessionFactory level.
  • Query cache

Hibernate uses Level 1 cache to mainly reduce the number of SQL queries. It is always the default cache. If there are several modification on the same object it will simply generate a single SQL query for this. The level 1 cache is usually restrained to be for a single session, it is short lived. Essentially the general idea behind the fist level cache is that it batches queries.

A Level 2 cache is designed to interoperate between sessions. Level 2 cache is usually recommended when we are dealing with read only objects. It is not enabled by default. It is conceptually a map that has the id of the object as the key and the set of attributes the entity has as the value.

The Query cache is not on by default either. It uses two cache regions -

  • StandardQueryCache - stores the query along with the parameters as key to the cache region. So any subsequent queries with the same key will hit the query cache and retrieveĀ  the object from the cache
  • UpdateTimeStampsCache - tracks the timestamps of the most recent updates to particular tables to identify stale results

Remember all this caching will only be effective in reducing the number of queries if we use session.get to load the object. Using HQL to load the object may in fact create more queries.

Hibernate has four basic types of cache providers-

  • EHCache - fast, lightweight, read-only and read write caching support,memory and disk based caching , no clustering.
  • OSCache - read only and read write caching, memory and disk based caching, clustering support via JMS or JavaGroups.
  • SwarmCache - cluster based caching based on JavaGroups, read only and nonstrict read write caching, usually used when there are more read operations than write.
  • JBoss TreeCache - replicated and transactional cache.
  • Tangosol Coherence Cache

The caching strategy is specified using a <cache usage = “”> tag. The caching strategies maybe:

  • read only - for frequently read data, simple, best performer.
  • read-write - data needs to be updated, never used if serializable transaction isolation level is needed, need to specify a manager_lookup_class in JTA environment.
  • nonstrict read-write - rarely updating data , need to specify a manager_lookup_class in JTA environment.
  • transactional - only used in a JTA environment

If the hibernate.cache.provider_class property is set, second level cache is enabled. Cache can be configured within hibernate.cfg.xml. Cache’s usage patterns can be defined within the <cache> element in the hbm’s associated with each domain class. Enable query caching by setting hibernate.cache.use_query_cache to true and call the setCacheable(true) on the Query object. Query cache always uses the second level cache. The Cache is loaded whenever an object is passed to save(), update(), saveOrUpdate() or when retrieving objects using load(), get(), list(). Invoking flush() will synchronize the object with the database. Use evict() to remove it from cache. A CacheMode defines how a particular session interacts with second level cache -

NORMAL - read and write to cache,
GET - read but dont put,
PUT - write but dont read,
REFRESH - force refresh of cache for all items read fromt he database

Fetching strategies

A fetching strategy identifies how hibernate will fetch an object along with it’s associations once a query is executed. There are four types of strategies

  • Join Fetching - All associated instances are retrieved in the same SELECT using OUTER JOIN. But having too many of this can result in a huge chunk of the database coming into memory, cause performance hurdles there.
  • Select Fetching - This is the default strategy. A second SELECT retrieves associated entity or collection. This is usually lazy unless specified otherwise. This is extremely vulnerable to the N+1 select problem, so instead the join fetching can be enabled.
  • Subselect fetching - similar to select but retrieves associated collections for all entries fetched previously.
  • Batch fetching - optimization on select fetching where a batch of entities are retrieved in one select

As far as we are concerned, we pretty much use EHCache as our caching strategy and do a lot of join fetching / lazy select fetching based on our requirements.

Of course all these technical ideas are borrowed from these websites

http://acupof.blogspot.com/2008/01/background-hibernate-comes-with-three.html
http://www.devx.com/dbzone/Article/29685
http://www.hibernate.org/hib_docs/reference/en/html/

Tags: , ,

Copyright © 2010 “An Image of My Life” blog series All rights reserved. Theme by Laptop Geek.

Total hits: 59972