SessionFactoryImpl caches and reuses entity cache regions & natural id cache regions in determineEntityRegionAccessStrategy and determineNaturalIdRegionAccessStrategy using the cacheAccessStrategiesMap, so you can use the same cache region (in my case an Infinispan 8.0.1 cache) for multiple entity types.
However cache region access strategies are not cached for collections. When iterating over metadata.getCollectionBindings() a CollectionRegion is built each time by calling regionFactory.buildCollectionRegion(...).
Interestingly, the created access strategy is added to the cacheAccessStrategiesMap but that map is not used to reuse an access strategy for a collection.
Creating an access strategy for the same Infinispan cache twice causes an exception when the PutFromLoadValidator is added to the cache again. Stacktrace below:
Caused by: org.infinispan.commons.CacheConfigurationException: Detected interceptor of type [org.hibernate.cache.infinispan.access.NonTxInvalidationInterceptor] being added to the interceptor chain 494540132 more than once!
at org.infinispan.interceptors.InterceptorChain.assertNotAdded(InterceptorChain.java:76)
at org.infinispan.interceptors.InterceptorChain.addInterceptor(InterceptorChain.java:90)
at org.infinispan.cache.impl.CacheImpl.addInterceptor(CacheImpl.java:880)
at org.hibernate.cache.infinispan.access.PutFromLoadValidator.<init>(PutFromLoadValidator.java:192)
at org.hibernate.cache.infinispan.access.PutFromLoadValidator.<init>(PutFromLoadValidator.java:133)
at org.hibernate.cache.infinispan.impl.BaseTransactionalDataRegion.prepareForValidation(BaseTransactionalDataRegion.java:137)
at org.hibernate.cache.infinispan.impl.BaseTransactionalDataRegion.createAccessDelegate(BaseTransactionalDataRegion.java:122)
at org.hibernate.cache.infinispan.collection.CollectionRegionImpl.buildAccessStrategy(CollectionRegionImpl.java:49)
at org.hibernate.internal.SessionFactoryImpl.<init>(SessionFactoryImpl.java:400)
at org.hibernate.boot.internal.SessionFactoryBuilderImpl.build(SessionFactoryBuilderImpl.java:444)
at org.hibernate.boot.internal.MetadataImpl.buildSessionFactory(MetadataImpl.java:170)
I can workaround this issue by using separate caches for each collection, however I believe this is a fault that could be alleviated by caching and reusing CollectionRegionAccessStrategy}}s in the same way that entities do, and given that the access strategies are added to {{cacheAccessStrategiesMap but not retrieved, I figure this is an oversight.
I have created a patch for this, and will add a pull request to this ticket. This corrected the issue for me except that Hibernate 5.0 appears to not support using the same cache region for multiple entities in read-write access mode... I'll ask about that another time.
|