Monday, July 2, 2012

Hibernate EHCache: Cache Invalidation Unable to Find SessionFactory

Using Hibernate 3.6.10 and EHCache 2.5.1, I encountered the following error in the log (in the receiving server) when a cache invalidation message was replicated from one node to another.

failed calling receive() in receiverjava.lang.IllegalArgumentException: java.lang.NullPointerException
       at org.jgroups.Message.getObject(Message.java:291)
       at net.sf.ehcache.distribution.jgroups.JGroupsCacheReceiver.
receive(JGroupsCacheReceiver.java:62)
       at org.jgroups.JChannel.up(JChannel.java:1490)
       at org.jgroups.stack.ProtocolStack.up(ProtocolStack.java:1074)
<<<<<<<<<<<<<<<<<<<<< SNIPPED >>>>>>>>>>>>>>>>>>>>>>>
       at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
       at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
       at java.lang.Thread.run(Thread.java:662)
Caused by: java.lang.NullPointerException
       at java.util.concurrent.ConcurrentHashMap.get(ConcurrentHashMap.java:768)
       at org.hibernate.impl.SessionFactoryObjectFactory.getNamedInstance
(SessionFactoryObjectFactory.java:159)
       at org.hibernate.impl.SessionFactoryImpl.readResolve(SessionFactoryImpl.java:753)
       at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
       at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
       at sun.reflect.DelegatingMethodAccessorImpl.invoke
(DelegatingMethodAccessorImpl.java:25)

<<<<<<<<<<<<<<<<<<<<< SNIPPED >>>>>>>>>>>>>>>>>>>>>>>
       at java.io.ObjectInputStream.readObject(ObjectInputStream.java:350)
       at org.jgroups.util.Util.objectFromByteBuffer(Util.java:398)
       at org.jgroups.Message.getObject(Message.java:288)

The cause of this is Hibernate not being able obtain the SessionFactory instance in the receiving server. In Hibernate, it tries to obtain the SessionFactory instance using the UUID. Since this UUID was being generated randomly in both nodes, there is no chance of both UUIDs being the same. This lookup will therefore fail.

However, the fallback mechanism is to lookup using the JNDI name of the SessionFactory, which I did not set. The solution is to set the JNDI name using the "hibernate.session_factory_name" property on both nodes. After I have done that, this problem doesn't happen anymore and replication/cache invalidation is successful.

No comments:

Post a Comment