Issue Details (XML | Word | Printable)

Key: NUCCORE-595
Type: New Feature New Feature
Status: Closed Closed
Resolution: Fixed
Priority: Major Major
Assignee: Andy Jefferson
Reporter: Andy Jefferson
Votes: 2
Watchers: 1
Operations

If you were logged in you would be able to see more operations.
DataNucleus Core

Ability to "persist" transient instances as way of updating existing objects

Created: 13/Nov/10 05:57 PM   Updated: 01/Aug/11 10:23 AM   Resolved: 16/Jun/11 12:11 PM
Component/s: Persistence
Affects Version/s: None
Fix Version/s: 3.0.0.m6


 Description  « Hide
If a user has taken a transient instance and updated it (with its application id field(s) set) they may want to be able to "attach" the changes and update the datastore object. JDO and JPA don't currently allow for this, but for application identity cases it could be made to work

Peter Rainer added a comment - 24/Jan/11 01:26 PM
As discussed with Andy in the forum (http://www.datanucleus.org/servlet/forum/viewthread_thread,6515) it's currently not possible to persist transient instances (meaning instances which have a the same id as a persistent object but are new object instances which have not been detached from a persistence context previously) as updates. Currently a new id as generated and the object is persisted as new instance.

* As the main reason for persisting it as new object is that the enhancer generated method "jdoIsDetached()" in the entity returns false part of the change needs to be done in the enhancer
  public boolean jdoIsDetached() { return (this.jdoStateManager == null) && (this.jdoDetachedState != null); }
* There is a difficulty with primitive data types as they are not nullable ans therefore do always have an id, but not identity as they are initialized with default values, therefore I'll first try to look at the reference types and only afterwards try to find a solution for primitive types

Andy Jefferson added a comment - 24/Jan/11 01:51 PM
The problem is *not* the enhancement contract, and this is well defined in the JDO spec, as are object lifecycle states. The enhancement contract will not be changing, nor will lifecycle state definition.

The problem (this JIRA) is passing in a transient object in to ObjectManager.persistObject() and what to do if the object is using application identity and already has its identity fields set and an object with that identity exists in the datastore. To implement such a thing you need to define a new persistence property called something like
datanucleus.persistTransientExisting
Default behaviour will throw an exception (like it does now). Setting this persistent property to some other value can instead go to the datastore and check object existence, and then update the field values of the persistent object. You'll need to create a FieldManager to manage the copying in of field values from the transient object to the persistent object (and temporarily connect the transient object to a StateManager so its field values can be accessed).

Peter Rainer added a comment - 24/Jan/11 02:18 PM
Thanks for the feedback I'll take a look at it and see how much work is involved in changing that

by the way - it's currently only throwing an exception if the id field is not annotated with @GeneratedValue - if it's annotated it's creating a new id and persisting the object as a "duplicate" of the original one

Andy Jefferson added a comment - 15/Jun/11 08:53 PM
"test.jpa.general" EntityManagerTest has a test for merge of a transient that represents an object in the datastore and expects an attach. Such functionality would, when written, be enabled by the persistence property "datanucleus.allowAttachOfTransient".

Obviously the fact that 6+ months after raising this issue as a placeholder and now having to generate a test myself, people aren't so needing of this feature ... otherwise they would have contributed the test long ago.

Andy Jefferson added a comment - 16/Jun/11 12:11 PM
SVN trunk allows the previously mentioned persistence property to check for existence of a persistent object (with same id as the transient object) and, if it exists, merge the changes from transient into persistent.

Tested on simple case with no relations - left as exercise to these people who were so keen for this to actually provide tests on other situations

Andy Jefferson made changes - 16/Jun/11 12:11 PM
Field Original Value New Value
Status Open [ 1 ] Resolved [ 5 ]
Assignee Andy Jefferson [ andy ]
Fix Version/s 3.0.0.m6 [ 11266 ]
Resolution Fixed [ 1 ]
Andy Jefferson made changes - 01/Aug/11 10:23 AM
Status Resolved [ 5 ] Closed [ 6 ]