Archive

Archive for June 27th, 2009

Overcoming pitfalls with Query cache in Hibernate

June 27th, 2009 Shrihari No comments

Query caching in Hibernate used to cache query state and results, has  multiple shortcomings if, not used judiciously. Some of the common pitfalls include:

(i) Query Cache structural representation is a QueryKey mapped to Object[][] (2-dimensional)  and holds majority of persistent object references. QueryKey represents query specific data such as the SQL Query text with parameters (positional/named). QueryKey representation would get deteriorated if parameters represent entity object or a deep rooted object hierarchy.

(ii) If multiple equivalents of load() is invoked,  there could potentially create multiple parameter versions of QueryKey containing equivalent duplicate entity objects exist in the cache.

Following are the patterns and practices that could be followed to fix these shortcomings:

1) Decorate org.hibernate.cache.StandardQueryCache and override the put() method to check if a canonical equivalent of a query results object already exist in the Object[][], and assign the same QueryKey if it exists. One needs to implement org.hibernate.cache.QueryCacheFactory also to plug into the Hibernate config.

2) Refactor the code to set entity’s keys as query parameters, rather than setting the entire entity object. Critreia representations should also use identifiers as parameters.

3) Write HQL queries to use identifiers in any substitutable parameters such as WHERE clause, IN clause etc.

4) Use positional parameters over named parameters as it could prevent using string pools.

5) If you are in a single JVM using in memory cache only, use hibernate.cache.use_structured_entries=false in your hibernate configuration.

Categories: Uncategorized Tags: ,

Hibernate Session's get() annd load() comparison

June 27th, 2009 Shrihari No comments

These are the differences I could readily understand when I was comparing the runtime behaviour of Hibernate Session’s get and load methods.

a)    get() does a database hit as soon as the method is called, load() makes a database hit, only if one of the field in the entity is called.

b)    load() should be used when the entity is assured that it exists in the database, else get() should be called. If an non-existent primary key is passed, get() returns a null directly. However passing a non-existing primary key to load() returns you a non-null entity object, but would throw this exception when a field of that entity is referenced: org.hibernate.ObjectNotFoundException: No row with the given identifier exists.

c)    calling a field in the entity in load() method after getTransaction().commit(), would throw a LazyInitializationException (could not initialize proxy – no Session).


Categories: Uncategorized Tags: