Richard Zowalla created OPENJPA-3022:
----------------------------------------
Summary: Loading a field of an instance with unflushed changes
stores those changes in the data cache
Key: OPENJPA-3022
URL: https://issues.apache.org/jira/browse/OPENJPA-3022
Project: OpenJPA
Issue Type: Bug
Reporter: Richard Zowalla
Assignee: Richard Zowalla
With the data cache enabled, loading a field of an instance that has unflushed
changes stores those changes in the data cache. When the transaction is then
rolled back, other persistence contexts read the rolled back values from the
cache.
{code:java}
em.getTransaction().begin();
Entity e = em.find(Entity.class, id); // cached without the lazy field
e.setName("dirty");
e.getLazyField(); // loads from the database
em.getTransaction().rollback();
// new EntityManager
em2.find(Entity.class, id).getName(); // "dirty"
{code}
This applies to any field type, including relations.
Found by the Apache Syncope tests: a test adds an invalid element to a list
attribute, the validation in the DAO throws before any flush, and the test
transaction is rolled back. Later tests in the same class read the invalid
element for the same entity.
Cause: {{DataCacheStoreManager.load()}} calls {{updateDataCache()}} when it
loaded fields from the database, and {{cacheStateManager()}} calls
{{DataCachePCData.store(sm)}}, which stores all loaded fields of the instance.
It only skips flushed instances, not dirty ones. {{loadAll()}} does the same
with {{data.store(sm)}} for instances that were not in the cache.
The cache should only be filled from state read from the database, so a dirty
instance should not be stored, or only its clean fields.
--
This message was sent by Atlassian Jira
(v10.3.26#10030026)