开发者

How to run multiple Hibernate SessionFactories with the SAME db schema using a distributed Ehcache

We have a system with n number of clients (55 at this time) where each client gets their own database all of which have the exact same schema. We are running hibernate 3.6.1 backed by a distributed ehcache. This has been implemented with a SessionFactory per database via a SessionFactoryService that at run time "lazily" creates one SessionFactory per client per jvm (stored in a HashMap), so we are running an Application managed set of SessionFactories. There is one basic hibernate configuration file with the remainder of the settings done programmatically at creation time. Our repositories (or DAOs as they are more commonly referred to) are given access to the SessionFactory via the SessionFactoryService. We are taking full advantage of the hibernate second level cache backed by a SingltonEhcacheRegionFactory which is distributed. Because we are running n number of SessionFactories per jvm, we do not want a NON SingltonEhacheRegionFactory (i.e. having a CacheManager per SessionFactory) as there will be too much inter jvm communication between SessionFactories while trying to maintain synchronization across caches. So what we want is only communication across servers NOT communication within a server and this has been achieved via the SingltonEhcacheRegionFactory.

Now, here is where the fun starts. With the above setup, there will be cache collisions as there is no way to guarantee unique keys as the database schemas and hence the entity objects backing them are the same across SessionFactories. In order to make them unique, we have set the field hibernate.cache.region_pre-fix to a unique value per SessionFactory via the programmatic configuration step above. This satisfies Hibernate's view of the second level cache BUT the underlying singleton ehcache now has an issue. It cannot find the correct configuration as the configurations specified in the ehache.xml config file don't have the cache prefix on the cache name (nor could they as there would have to be a duplicate entry for each cache configuration for each prefix, of which there are n number). This causes the below error:

10:37:38,389 WARN AbstractEhcacheRegionFactory:201 - No TransactionManagerLookup found in Hibernate config, XA Caches wi开发者_Python百科ll be participating in the two-phase commit! 10:37:39,675 WARN AbstractEhcacheRegionFactory:143 - Couldn't find a specific ehcache configuration for cache named [some_prefix.adc]; using defaults. 10:37:40,328 WARN AbstractEhcacheRegionFactory:143 - Couldn't find a specific ehcache configuration for cache named [some_prefix.org.hibernate.cache.UpdateTimestampsCache]; using defaults. 10:37:40,331 WARN AbstractEhcacheRegionFactory:143 - Couldn't find a specific ehcache configuration for cache named [some_prefix.org.hibernate.cache.StandardQueryCache]; using defaults.

So the question is, how can we accomplish a multiple SessionFactory with a distributed singlton ehcache per jvm environment? Is there a way to configure ehcache to be region pre-fix aware? The solution we have implemented is hacky at best. We have implemented our own hibernate.cache.region.factory_class which extends SingltonEhcacheRegionFactory (and removed the hibernate cache region prefix config). All our implementation does is intercept method calls to the underlying Ehcache and appends a pre-fix to all keys used for cache operations, thereby preventing cache collisions. We would like a more "out of the box" solution and for obvious reasons what we have implemented though it works, is not ideal. I have read everything I can possibly find on the matter and haven't found a solution that address multiple SessionFactories with the SAME SCHEMA (and most importantly) using a distributed second level cache. Any ideas, solutions, or advice would be much appreciated. I am even open to an entirely different design if someone has a good way to address the requirements. Thanks in advance!


With the above setup, there will be cache collisions as there is no way to guarantee unique keys as the database schemas and hence the entity objects backing them are the same across SessionFactories

What do you mean? If you are using the same schema for all clients, there is certainly a way to guarantee unique keys. There are a lot of techniques for this, including using UUID or using Hibernate's hilo algorithm.

In order to make them unique, we have set the field hibernate.cache.region_pre-fix to a unique value per SessionFactory via the programmatic configuration step above

Not sure I understood. You mean that to be able to get unique keys you need different cache regions? If so, that's not true :-) Cache regions are supposed to be a "namespace" for entities (Car, Person, Account), not for entries (Car#1, Car#2).

how can we accomplish a multiple SessionFactory with a distributed singlton ehcache per jvm environment?

Multiple session factories are not a problem. Not sure about ehcache, but I would consider using a "Cache server", like Infinispan. You can start it in its own JVM, and all clients would talk to it whenever they want to access the cache. Again, not sure I understood your environment correctly, but when using a cache, you should use a setup which ensures that the data that Client#1 sees is the same as Client#2.

So, I would setup an environment with a dedicated cache server, configuring all session factories to use it. Also, one bit that you missed in your description is the transaction manager. When dealing with distributed environments, transaction management is really important, to ensure that the data in the cache (and database) are not stale and are consistent.

You can read more about Infinispan with Hibernate here: http://community.jboss.org/wiki/usinginfinispanasjpahibernatesecondlevelcacheprovider

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜