![]() |
![]() |
|
[
Permalink
| « Hide
]
Peter Dettman added a comment - 12/Apr/10 05:59 PM
Proposed patch and test case (both against respective 2.0 branch).
To briefly describe the patch:
1. Fix minor issue relating to the id that detached copy objects were stored against in DetachState: detached copies were being stored against "StateManager.getExternalObjectId", but looked up via "ApiAdapter.getIdForObject". It now consistently uses the ApiAdapter one. 2. DetachState tracks extra information for each detached copy about the state of the FetchPlanState at the time(s) it was detached. Redundant entries (as determined by a "dominance" algorithm) are not kept, so the size of this information ought to be small in practice (and even in the worst-case, bounded by the number of fields for the type). 3. ObjectManagerImpl.detachObjectCopy delegates the detached object cacheing to the StateManager. 4. JDOStateManagerImpl.detachCopy now handles the DetachState interaction. When an already-detached object is encountered again (other than the trivial nested occurrence), the current FetchPlanState is compared to the information from previous detaches to see whether further processing is required. As it stands, the algorithm is conservative. It ensures efficiency for the important case of sibling objects in a collection. It could do better in the general case with access to the FetchPlan information. Some local optimisations remain to be done in DetachState e.g. the full fetchFieldNames list isn't really required in the Entry objects. 5. If the current detached object is not sufficient, detachCopy algorithm is run on the existing object again, being careful to retrieve information about the existing loaded fields so none will be lost. ---------- I've attached a test case, but this patch also fixes "org.datanucleus.tests.knownbugs.AttachDetachTest.testFetchDepthOnDetachCopyAll", which I only belatedly realised was there. They are quite similar. Issues: 1. Transient objects: in JDOStateManagerImpl, the first time a non-Detachable object is detachCopy'ed, it is made transient. Per this patch, detachCopy may be attempted on that object again. Is it safe to call JDOStateManagerImpl.initializeForDetached on a transient instance? Also, will JDOStateManagerImpl.retrieveDetachState then work on that instance? 2. With the patch applied, the DetachLifecycleListener listeners may be called more than once for a given object during detachCopy. Is this a spec violation? Is it problematic in other ways? Thx for the patch. The one for core is applied to SVN trunk. Not bothered with the testcase, and moved the "knownbugs" case to the main test area now that it passes. DN unit tests pass as before, as does JDO2 TCK and JPA1 TCK.
Re: questions, 1. calling JDOStateManagerImpl.initializeForDetached would likely be a bad thing to do. If the user is calling detachCopy on something non-detachable then it is usually user error anyway (where they forgot to make the class detachable). Not an issue for JPA usage since everything is detachable. 2. whether the call of DetachLifecycleListener causes a JDO spec issue is unknown off the top of my head, but the TCK passes so either is not an issue or is not tested, so leave it alone until the issue comes up. Thanks for the quick turnaround, and I'm happy with those answers.
Part of the patch was not applied (JDOStateManagerImpl line 3829): + // If detached copy already existed, take note of fields previously loaded + if (existingDetached != null) + { + smDetachedPC.retrieveDetachState(smDetachedPC); + } and I'm curious if it was an oversight or deemed to be unnecessary. Granted the current test cases do not reveal a problem, so either way I suppose a failing test case is in order. Wasn't applied since your patch did not apply (to JDOStateManagerImpl, and to one of the XXXState classes) and had to be hacked in manually. Will look at it later.
|
|||||||||||||||||||||||||||||||||||||