JDO : Object Lifecycle

During the persistence process, an object goes through lifecycle changes. Below we demonstrate the primary object lifecycle changes for JDO

JDO has a very high degree of flexibility and so can be configured to operate in different modes. The mode most consistent with JPA is shown below (this has the PMF property DetachAllOnCommit set to true)

So a newly created object is transient. You then persist it and it becomes persistent. You then commit the transaction and it is detached for use elsewhere in the application. You then attach any changes back to persistence and it becomes persistent again. Finally when you delete the object from persistence and commit that transaction it is in transient state.

An alternative JDO lifecycle occurs when you have DetachAllOnCommit as false. Now at commit the object moves into hollow state (still has its identity, but its field values are optionally unloaded). Set the persistence property datanucleus.RetainValues to not unset the values of any non-primary-key fields when migrating to hollow state.

With JDO there are actually some additional lifecycle states, notably when an object has a field changed, becoming dirty, so you get an object in "persistent-dirty", "detached-dirty" states for example. The average user doesn't need to know about these so we don't cover them here. To inspect the lifecycle state of an object, simply call

JDOHelper.getObjectState(obj);

See also :-


Helper Methods

In addition to the JDOHelper method above, JDO provides a series of other helper methods for lifecycle operations. These are documented on the Apache JDO site.

Further to this DataNucleus provides yet more helper methods

String[] fieldNames = NucleusJDOHelper.getDirtyFields(pc, pm);
String[] fieldNames = NucleusJDOHelper.getLoadedFields(pc, pm);

These methods returns the names of the dirty/loaded fields in the supplied object. The pm argument is only required if the object is detached


Boolean dirty = NucleusJDOHelper.isDirty(pc, "fieldName", pm);
Boolean loaded = NucleusJDOHelper.isLoaded(pc, "fieldName", pm);

These methods returns whether the specified field in the supplied object is dirty/loaded. The pm argument is only required if the object is detached


State Transition Lookup

The JDO spec defines all lifecycles transitions. This table provides a summary of some of the common ones. Please refer to the JDO spec for details. Key : T-Clean = Transient Clean, T-Dirty = Transient Dirty, P-New = Persistent New, P-Clean = Persistent Clean, P-Dirty = Persistent-Dirty, P-New-Deleted = Persistent New Deleted, P-Deleted = Persistent Deleted, P-Nontrans = Persistent Nontransactional

Method / Current State T-Clean T-Dirty P-New P-Clean P-Dirty Hollow P-New-Deleted P-Deleted P-Nontrans
pm.makePersistent P-New P-New no change no change no change no change no change no change no change
pm.deletePersistent error error P-New-Deleted P-Deleted P-Deleted P-Deleted no change no change P-Deleted
pm.makeTransactional no change no change no change no change no change P-Clean no change no change P-Clean
pm.makeNontransactional no change error error P-Nontrans error no change error error no change
pm.makeTransient no change no change error T-Clean error T-Clean error error T-Clean
tx.commit
retainValues=false
no change T-Clean Hollow Hollow Hollow no change T-Clean T-Clean no change
tx.commit
retainValues=true
no change T-Clean P-Nontrans P-Nontrans P-Nontrans no change T-Clean T-Clean no change
tx.commit
DetachAllOnCommit=true
no change T-Clean Detached-Clean Detached-Clean Detached-Clean Detached-Clean T-Clean T-Clean Detached-Clean
tx.rollback
restoreValues=false
no change T-Clean T-Clean Hollow Hollow no change T-Clean Hollow no change
tx.rollback
restoreValues=true
no change T-Clean Transient P-Nontrans P-Nontrans no change Transient P-Nontrans no change
pm.refresh
active Datastore txn
no change no change no change no change P-Clean no change no change no change no change
pm.refresh
active Optimistic txn
no change no change no change no change P-Nontrans no change no change no change no change
pm.evict no change no change no change Hollow no change no change no change no change Hollow
read field
outside txn
no change P-Nontrans no change
read field
active Datastore txn
no change no change no change no change no change P-Clean error error P-Clean
read field
active Optimistic txn
no change no change no change no change no change P-Nontrans error error no change
write field/makeDirty
outside txn
no change P-Nontrans P-Nontrans-Dirty
write field/makeDirty
active txn
T-Dirty no change no change P-Dirty no change P-Dirty error error P-Dirty
retrieve()
outside txn or with active Optimistic txn
no change no change no change no change no change P-Nontrans no change no change no change
pm.retrieve()
with active Datastore txn
no change no change no change no change no change P-Clean no change no change P-Clean
pm.detachCopy()
outside txn, Nontx-read=true
error Detached-Clean Detached-Clean
pm.detachCopy()
outside txn, Nontx-read=false
error error Detached-Clean
pm.detachCopy()
active txn
Detached-Clean Detached-Clean Detached-Clean Detached-Clean Detached-Clean Detached-Clean error error Detached-Clean