| Summary: | ATTRIBUTES WITH FETCHTYPE.LAZY ARE POPULATED WITH REFERENCE TO SHARED CACHE | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|
| Product: | z_Archived | Reporter: | Vikram Bhatia <vikram.jeet.bhatia> | ||||||||
| Component: | Eclipselink | Assignee: | Nobody - feel free to take it <nobody> | ||||||||
| Status: | RESOLVED FIXED | QA Contact: | |||||||||
| Severity: | normal | ||||||||||
| Priority: | P3 | CC: | anssi.torma, tom.ware, vikram.jeet.bhatia | ||||||||
| Version: | unspecified | ||||||||||
| Target Milestone: | --- | ||||||||||
| Hardware: | PC | ||||||||||
| OS: | All | ||||||||||
| Whiteboard: | |||||||||||
| Attachments: |
|
||||||||||
|
Description
Vikram Bhatia
This issue is caused by weaving. In case of weaving, PersistenceEntityCopyPolicy is the default policy, which calls a method added by weaving PersistenceObject)object)._persistence_shallow_clone() This method uses Object.clone() for cloning the original cache object to working copy object. Workaround: Use a CloneCopyPolicy. Created attachment 210208 [details]
Proposed Fix including testcase
Created attachment 210301 [details]
Fix with additional steps in testcase
Checked into main trunk with r10764. The same issue will occur in a refresh(), or merge(). So, re-opening the bug to implement the fix in a better way to fix all the issues. After an object is cloned, each of its value holders will be replaced with a unit of work value holder. Any time we set a value holder to a new value, the mirror variable should be reset. If the mirror is not being reset when we set the value of the value holder, then that needs to be fixed, not shallow clone. Could you elaborate on how to use a CloneCopyPolicy as a workaround? We've been hit quite badly with problems that relate to the shared cache of EclipseLink and editing an entity across http requests while storing in a http session. The main entity is a fairly complex one with bidirectional one-to-many, private-owned associations to child entities that are also edited. I can observe a scenario where the entity instance in the shared cache is modified since other sessions can see changes done by one session without the latter committing any transaction. Also, when finally merged/persisted, not all changes are actually saved to the database. I believe this is a result of change tracking going wrong due to modification of the shared cache instance. In another scenario, I'm getting an EclipseLink error reporting an attempt to modify a many-to-one id association modified, even though no such changes have actually been done. Both these problems are avoided by disabling the shared cache, which unfortunately is not a viable solution in a production environment. Scenario 1 is also fixed by making a lazy loaded, basic lob field eagerly loaded (though that will create other problems). I've had to resort to implementing a clone() method that deep-copies the whole entity graph and putting the copy in a http session for editing instead of the EclipseLink managed instance. That workaround leaks knowledge of the persistence framework and its problems to other layers. Unfortunately I haven't been able to reproduce these problems in a simple test case. What I was trying to hint at in my previous comment is my hope of this bug getting prioritised higher :) Created attachment 211710 [details]
Patch overriding earlier fix and fix testcase issue with no-weave option.
Fixed with r10911. Backported the fix to 2.3.4 with commit id d7ee7b2ebbfbe70d6fcbafbbce2f8e4649de35e6 This is not fully fixed, or at least the fix is not ported to the latest EclipseLink versions 2.4.2 and 2.5.1. My test case is a cacheable entity tree with TWO layers of lazy-loaded one-to-many associations, A <1--*> B <1--*> C. I'm loading an instance of A for editing in two different HTTP sessions. When I remove or add an instance of entity C from the graph, it's reflected in the other session without any merge (or any transaction). However, if I convert the associations to eager loaded, the problem is gone. There's also no problem when adding/removing B instances, suggesting the fix (if any) doesn't apply transitively to the entire entity graph. I would also raise the priority of this bug. Consider e.g. a battery of integration tests, each of which is rolled back at the end (like Spring-managed integration tests). If one tests manipulates an object that's populated with reference to shared cache, the next test may fail due to incorrect data, causing hard-to-find bugs. Not to mention potentially invalid data saved in a production application... The Eclipselink project has moved to Github: https://github.com/eclipse-ee4j/eclipselink |