I have just discovered that the ignite hibernate layer 2 cache region
factory does something weird with tracking changes - the wrong regions/caches were being updated - I would end up with cache entries for other regions in one region. for example if I say loaded updated a product entity then updated a customer entity the product cache could contain the update to the customer. It looks like someone didn't finish the implementation as there was a note in source : /** Map needed to provide the same transaction context for different regions. */ So I made the following two lines of change in modules/hibernate/src/main/java/org/apache/ignite/cache/hibernate/HibernateRegionFactory Line 102 in 1.8 : - private final ThreadLocal threadLoc = new ThreadLocal(); + private ConcurrentMap<String, ThreadLocal> threadLocMap = new ConcurrentHashMap<>(); Line 222 in 1.8 : ThreadLocal threadLocalForCache(String cacheName) { - return threadLoc; + return threadLocMap.computeIfAbsent(cacheName, (k)->new ThreadLocal());; } Cameron |
Hello, Cameron,
Thanks for reporting this. *Sam*, could you confirm that this is a valid fix or suggest a proper one filing a JIRA issue? — Denis > On Feb 26, 2017, at 1:25 AM, Cameron Braid <[hidden email]> wrote: > > I have just discovered that the ignite hibernate layer 2 cache region > factory does something weird with tracking changes - the wrong > regions/caches were being updated - I would end up with cache entries for > other regions in one region. > > for example if I say loaded updated a product entity then updated a > customer entity the product cache could contain the update to the customer. > > It looks like someone didn't finish the implementation as there was a note > in source : /** Map needed to provide the same transaction context for > different regions. */ > > So I made the following two lines of change in > modules/hibernate/src/main/java/org/apache/ignite/cache/hibernate/HibernateRegionFactory > > Line 102 in 1.8 : > > - private final ThreadLocal threadLoc = new ThreadLocal(); > + private ConcurrentMap<String, ThreadLocal> threadLocMap = new > ConcurrentHashMap<>(); > > Line 222 in 1.8 : > > ThreadLocal threadLocalForCache(String cacheName) { > - return threadLoc; > + return threadLocMap.computeIfAbsent(cacheName, (k)->new > ThreadLocal());; > } > > > Cameron |
In reply to this post by Cameron Braid
Hi,
Thank you for reporting this bug, but it seems fix you suggested will not work for HibernateReadWriteAccessStrategy since single thread local is needed to use single cross-cache transaction. I created JIRA issue: https://issues.apache.org/jira/browse/IGNITE-4760. Thanks! On Sun, Feb 26, 2017 at 12:25 PM, Cameron Braid <[hidden email]> wrote: > I have just discovered that the ignite hibernate layer 2 cache region > factory does something weird with tracking changes - the wrong > regions/caches were being updated - I would end up with cache entries for > other regions in one region. > > for example if I say loaded updated a product entity then updated a > customer entity the product cache could contain the update to the customer. > > It looks like someone didn't finish the implementation as there was a note > in source : /** Map needed to provide the same transaction context for > different regions. */ > > So I made the following two lines of change in > modules/hibernate/src/main/java/org/apache/ignite/cache/hibernate/ > HibernateRegionFactory > > Line 102 in 1.8 : > > - private final ThreadLocal threadLoc = new ThreadLocal(); > + private ConcurrentMap<String, ThreadLocal> threadLocMap = new > ConcurrentHashMap<>(); > > Line 222 in 1.8 : > > ThreadLocal threadLocalForCache(String cacheName) { > - return threadLoc; > + return threadLocMap.computeIfAbsent(cacheName, (k)->new > ThreadLocal());; > } > > > Cameron > |
In reply to this post by Cameron Braid
Hello everybody!
Cameron write please. How did you recreated mistake that the wrong regions/caches were being updated? I tried to do it in HibernateL2CacheConfigurationSelfTest.java - testEntityCacheNonStrictFails. After: e2forUpdate.setName("XXXXXXX"); session.update(e2forUpdate); Both regions for Entity1 and Entity2 get updates and assert fails: assertEquals(1, sessionFactory.getStatistics().getSecondLevelCacheStatistics(ENTITY1_NAME).getPutCount());
|
Free forum by Nabble | Edit this page |