Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JPA: How do I synchronize the persistence context with the result of the bulk update or delete?

There's a statement in the ejb-3_0-fr-spec-persistence.pdf which reads

The persistence context is not synchronized with the result of the bulk update or delete

So if I do a query.executeUpdate which deletes rows from a table. Those same rows still exist in another entities one to many collection. When I restart the application, I see the phantom entities are now removed from the collection.

So is there a (nice\simple\generic) way of synchronizing JPA's cache with the result of a bulk update\delete ?

BTW. Im using EclipseLink, version: Eclipse Persistence Services - 1.1.0.r3634.

Thanks,

Phil.

like image 560
Phil Avatar asked Sep 23 '09 21:09

Phil


4 Answers

You have to be careful of how you use the word "cache" here for it may mean different things.

The highlighted phrase talks about persistence context, which can be thought of as "1st level cache". In order to update it with the latest changes from the database you can either:

  1. Call EntityManager.refresh() to refresh state of a single entity.
  2. OR discard entity manager instance altogether (after flushing / clearing changes as appropriate) and obtain a new one from entity manager factory. Any entities you load from within this new instance will be loaded from database and thus contain latest changes.

Then there also may be a "2nd level cache" which is not bound to a particular entity manager. You can refresh it (or, rather, clear and let it repopulate itself) using its own API (differs between cache providers).

like image 199
ChssPly76 Avatar answered Sep 24 '22 10:09

ChssPly76


This is how you clear the cached data.

entityManager.getEntityManagerFactory().getCache().evictAll();
like image 28
FAtBalloon Avatar answered Sep 22 '22 10:09

FAtBalloon


The persistence context is not updated to reflect results of update and delete operations. If you use a transaction-scoped persistence context, you should either execute the bulk operation in a transaction all by itself, or be the first operation in the transaction (see Introduction to EclipseLink Transactions). That is because any entity actively managed by the persistence context will remain unaware of the actual changes occurring at the database level.

Fell comfortable to knock me here at http://puspendu.wordpress.com/2010/12/22/sync-jpa-database-multiple-application/

like image 20
Puspendu Banerjee Avatar answered Sep 23 '22 10:09

Puspendu Banerjee


The 1st level cache (EntityManager/transaction) will need to be manually refreshed or cleared. You can either refresh the objects, call clear(), or get a new EntityManager.

The 2nd level cache (shared cache) should get automatically invalidated when you commit the transaction. If it is not for some reason, then you can use the JPA Cache API, or EclipseLink JpaCache API to evict or invalidate the objects, or you could refresh them.


like image 32
James Avatar answered Sep 23 '22 10:09

James