Sunday, May 14, 2006

Lookup or Reference Data, Hibernate and Second Level Caching

Using hibernate's second level caching with read-only caching for a class leads to following error:

Exception in thread "main" java.lang.UnsupportedOperationException: Can't write to a readonly object
at org.hibernate.cache.ReadOnlyCache.lock(ReadOnlyCache.java:43)
at org.hibernate.action.EntityUpdateAction.execute(EntityUpdateAction.java:77)
at org.hibernate.engine.ActionQueue.execute(ActionQueue.java:243)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:227)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:141)
at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:296)
at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:27)
at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:980)
at org.springframework.orm.hibernate3.HibernateAccessor.flushIfNecessary(HibernateAccessor.java:394)
at org.springframework.orm.hibernate3.HibernateTemplate.execute(HibernateTemplate.java:366)
at org.springframework.orm.hibernate3.HibernateTemplate.get(HibernateTemplate.java:445)
at org.springframework.orm.hibernate3.HibernateTemplate.get(HibernateTemplate.java:439)
at com.isd.common.persistence.dao.BaseDaoHibernate.get(BaseDaoHibernate.java:33)
at com.isd.common.service.lookupcache.LookupCacheManagerImpl.getLookupType(LookupCacheManagerImpl.java:61)
at com.isd.common.service.lookupcache.TestLookupCache.main(TestLookupCache.java:36)


The mapping for corresponding class is as follows:

<!-- Lookup tables -->
<class name="com.isd.common.service.lookupcache.LookupType" table="LookupType" dynamic-update="false">
<cache usage="read-only"/>
...
...


The reason for the error is that hibernate tries to flush the session after the get and implictly issues save/update even thoough nothing has changed.

This error can be resolved by setting mutable="false" for the class mapping in hibernate mapping for the cacheable object. This tells hibernate that no update is required for an existing object (record). Modifying the above mapping to following will fix the problem:


<!-- Lookup tables -->
<class name="com.isd.common.service.lookupcache.LookupType" table="LookupType" mutable="false" dynamic-update="false">
<cache usage="read-only"/>


Second cache configuration setting have not been shown in above snippets.

This page is powered by Blogger. Isn't yours?