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)

Reply via email to