L2 entity cache is evicted prior to committing transaction for HQL/native updates

Description

This issue occurs when using a read-write cache concurrency strategy, and applying an update or delete as part of an HQL or native sql query.

The L2 entity cache gets cleared before the transaction is committed.

This can lead to scenarios where a different session is able to populate the cache with the old data, leaving the cache out-of-date.

Activity

Show:

balram patel May 4, 2022 at 10:12 AM

Frank Doherty December 21, 2019 at 7:34 AM

I have created a pull request here: https://github.com/hibernate/hibernate-orm/pull/3152

It includes some func tests (update and delete for HQL/native queries) which:

  • confirmed the problem (they are failing when run without the suggested fix)

  • are passing when the suggested fix is included

 

Frank Doherty December 21, 2019 at 6:59 AM

It looks like the BulkOperationCleanupAction.EntityCleanup constructor (called during the transaction) is calling cacheAccess.removeAll( session );

In the case of EntityReadWriteAccess this invokes the removeAll method inherited from AbstractCachedDomainDataAccess, which does:

getStorageAccess().clearCache( session );

 

So the cache is cleared here before the transaction is committed.

 

Also note that the release method inBulkOperationCleanupAction.EntityCleanup (called after the transaction is committed) calls cacheAccess.unlockRegion( cacheLock );

In the case of EntityReadWriteAccess this is a no-op.

 

(One possible approach might be to change EntityReadWriteAccess so that removeAll is the no-op and unlockRegion performs the cache eviction.)

Fixed

Details

Assignee

Reporter

Worked in

Components

Fix versions

Affects versions

Priority

Created December 21, 2019 at 6:49 AM
Updated May 4, 2022 at 10:12 AM
Resolved February 5, 2020 at 2:48 PM