[Logo] Terracotta Discussion Forums (LEGACY READ-ONLY ARCHIVE)
  [Search] Search   [Recent Topics] Recent Topics   [Members]  Member Listing   [Groups] Back to home page 
[Register] Register / 
[Login] Login 
[Expert]
Issue with replicated Hibernate StandardQueryCache  XML
Forum Index -> Ehcache
Author Message
hostalp

neo

Joined: 07/11/2013 02:31:10
Messages: 8
Offline

We use the configuration below to achieve one cache manager instance for Hibernate as well as for our caches. This works well, but in cluster (RMI replication) when the Hibernate StandardQueryCache is replicated, there's one problem.
https://hibernate.atlassian.net/browse/HHH-6162 - there's a reference to the Hibernate session factory held by some query cache objects and the only way to live with it is to name the Hibernate session factory (that's what we've done via hibernate.session_factory_name.
With our configuration the cache manager starts quite earlier than the session factory binds its JNDI name.
When the cache replication initializes, the cache manager will receive objects (with reference to the session factory) from the already running remote instance and because it happens before the session factory is locally available it will complain like shown below.

Now some questions:
- Will the below exception cause the replication for the StandardQueryCache region to not initialize at all, or will it be (silently) retried at the background and thus succeed later (when the session factory is available)?

- Any ideas for how to prevent that from happen at all? We tried to somewhat postpone the cache manager startup to later time (when the session factory exists) but no success so far. The entity manager factory initialization kicks in before session factory of course (and it takes some time so that there's some decent time gap - depending on the environment from few to few tens of seconds) and the cache manager is already required at this point. Session factory initialization follows afterwards and that's too late.

Ehcache 2.7.4, Hibernate 3.6.4, Spring 3.0.7

Code:
[Bootstrap Thread for cache org.hibernate.cache.StandardQueryCache] WARN  RMIBootstrapCacheLoader [] [] - Error asynchronously performing bootstrap. The cause was: Error bootstrapping from remote peer. Message was: error unmarshalling return; nested exception is: 
 	java.io.InvalidObjectException: Could not find a SessionFactory named: hibernate/SessionFactory
 net.sf.ehcache.distribution.RemoteCacheException: Error bootstrapping from remote peer. Message was: error unmarshalling return; nested exception is: 
 	java.io.InvalidObjectException: Could not find a SessionFactory named: hibernate/SessionFactory
 	at net.sf.ehcache.distribution.RMIBootstrapCacheLoader.doLoad(RMIBootstrapCacheLoader.java:176)
 	at net.sf.ehcache.distribution.RMIBootstrapCacheLoader$BootstrapThread.run(RMIBootstrapCacheLoader.java:107)
 Caused by: 
 java.rmi.UnmarshalException: error unmarshalling return; nested exception is: 
 	java.io.InvalidObjectException: Could not find a SessionFactory named: hibernate/SessionFactory
 	at sun.rmi.server.UnicastRef.invoke(UnicastRef.java:185)
 	at net.sf.ehcache.distribution.RMICachePeer_Stub.getKeys(Unknown Source)
 	at net.sf.ehcache.distribution.RMIBootstrapCacheLoader.doLoad(RMIBootstrapCacheLoader.java:146)
 	... 1 more
 Caused by: 
 java.io.InvalidObjectException: Could not find a SessionFactory named: hibernate/SessionFactory
 	at org.hibernate.impl.SessionFactoryImpl.readResolve(SessionFactoryImpl.java:755)
 ...

Now brief configuration info:
Cache manager stuff - it's just used to ensure only one cache manager instance is used throughout the application for both Hibernate and our own caches:
Code:
    <bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">
 	</bean>
 
 	<bean id="localConfigurableCacheRegionFactory" class="...ConfigurableCacheRegionFactory">
 		<property name="cacheManager" ref="cacheManager"/>
 	</bean>
 	
 	<bean id="abstractCacheFactory" class="...AbstractCacheBean" abstract="true">
         <property name="cacheManager" ref="cacheManager" />
     </bean>

Then Hibernate config follows:
Code:
    <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
     	<property name="persistenceUnitManager" ref="persistenceUnitManager" />
     	<property name="persistenceProvider">
     	 	<bean class="...ConfigurableHibernatePersistence">  
 	            <property name="interceptor">  
     	            <bean class="...HintSupportInterceptor"/>  
         	    </property>  
         	</bean> 
     	</property>
     	<property name="jpaVendorAdapter">
     		<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
 				<property name="showSql" value="${hibernate.showSql}" />
 				<property name="databasePlatform" value="${dataSource.dialect}" />
     		</bean>
     	</property>
     	<property name="jpaPropertyMap" ref="${transaction.mode}PropertyMap" />
     </bean>
 
 	<util:map id="webspherePropertyMap">
 		<entry key="hibernate.archive.autodetection" value=""/>
 		<entry key="hibernate.transaction.manager_lookup_class" value="org.hibernate.transaction.WebSphereExtendedJTATransactionLookup"/>
 		<entry key="hibernate.current_session_context_class" value="jta"/>
 		<entry key="hibernate.cache.region.factory_class" value="...ConfigurableCacheRegionFactory"/>
 		<entry key="hibernate.cache.use_query_cache" value="true"/>
 		<entry key="hibernate.generate_statistics" value="${hibernate.statistics}" />
 		<entry key="hibernate.session_factory_name" value="hibernate/SessionFactory" />
 	</util:map>
 
 	<bean id="sessionFactory" factory-bean="entityManagerFactory" factory-method="getSessionFactory" />

And our own caches are configured like:
Code:
	<bean id="nodeDao"
 		class="...JpaNodeDao">
 		<property name="cache">
 			<bean parent="abstractCacheFactory">
 				<property name="cacheName"
 					value="...NodeCache" />
 			</bean>
 		</property>
 	</bean>
hostalp

neo

Joined: 07/11/2013 02:31:10
Messages: 8
Offline

So as a simple workaround we created extended RMIBootstrapCacheLoaderFactory and RMIBootstrapCacheLoader that allow delayed start of bootstrap thread. Then we configured the delay to be long enough to ensure the Hibernate session factory is already available for the bootstrap.
It isn't the best solution, but as a simple one it works.
 
Forum Index -> Ehcache
Go to:   
Powered by JForum 2.1.7 © JForum Team