issue with Hibernate 2L cache region factory ignite-1.8

classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

issue with Hibernate 2L cache region factory ignite-1.8

Cameron Braid
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
Reply | Threaded
Open this post in threaded view
|

Re: issue with Hibernate 2L cache region factory ignite-1.8

dmagda
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

Reply | Threaded
Open this post in threaded view
|

Re: issue with Hibernate 2L cache region factory ignite-1.8

Semyon Boikov
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
>
Reply | Threaded
Open this post in threaded view
|

Re: issue with Hibernate 2L cache region factory ignite-1.8

vadopolski
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());




Cameron Braid 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