JDO recognizes several lifecycle states for persistence-capable objects. Instances transition between these states according to strict rules defined in the JDO specification. State transitions can be triggered by both explicit actions, such as calling the deletePersistent method of a PersistenceManager to delete a persistent object, and by implicit actions, such as reading or writing a persistent field.
The list below enumerates the lifecycle states for persistence-capable instances. Unless otherwise noted, each state must be supported by all JDO implementations. Do not concern yourself with memorizing the states and transitions presented; you will rarely need to think about them in practice.
![]() | Note |
---|---|
Some of the state transitions mentioned below occur at transaction boundaries. If you are unfamiliar with transactions, you may want to read the first few paragraphs of the chapter on the Transaction interface to become familiar with the concepts involved before continuing. |
Transient. Objects that are created via a user-defined constructor and have no association with the persistence framework are called transient objects. Transient objects behave exactly as if JDO does not exist.
A transient object transitions to persistent-new if it is the parameter of a call to the PersistenceManager's makePersistent method.
Persistent-new. The persistent-new state is reserved for objects that have been made persistent by a call to makePersistent, but have not yet been inserted into the data store. When an object transitions to the persistent-new state, it is given a JDO identity.
A persistent-new instance transitions to persistent-new-deleted if it is an argument to the PersistenceManager's deletePersistent method.
On transaction commit, the information in the persistent-new object is inserted into the data store. The object transitions to persistent-nontransactional if the Transaction's RetainValues property is set to true, otherwise it transitions to hollow. On transaction rollback, a persistent-new instance returns to the transient state. The data store is not affected. If the Transaction's RestoreValues property is set to true, the instance's persistent and transactional fields will be restored to the values they had when the transaction began.
Persistent-new-deleted. Objects that have been both persisted with makePersistent and then deleted with deletePersistent in the current transaction wind up in the persistent-new-deleted state. When objects are in this state, you are only allowed to access their primary key fields. Attempting to access any other persistent field will result in a JDOUserException.
A persistent-new-deleted object transitions to transient on transaction commit. The values of its persistent fields are replaced with Java default values. A persistent-new-deleted object also becomes transient if the transaction is rolled back. In this case, its persistent and transactional fields will be restored to the values they had when the transaction began if the Transaction's RestoreValues property is true, else they will be left untouched.
Persistent-clean. Objects that represent specific state in the data store and whose persistent fields have not been changed in the current transaction are persistent-clean.
A persistent-clean instance transitions to persistent-dirty if a change is made to any of its persistent fields. It transitions to persistent-deleted if it is the parameter of a call to the PersistenceManager's deletePersistent method. It transitions to persistent-nontransactional if it is the parameter of a call to makeNontransactional. It transitions to transient if it is the parameter of a call to makeTransient.
With the Transaction's RetainValues property set to true, a persistent-clean object transitions to persistent-nontransactional on transaction commit, otherwise it transitions to hollow. Correspondingly, with RestoreValues set to true, a persistent-clean object transitions to persistent-nontransactional on transaction rollback, otherwise it transitions to hollow.
Persistent-dirty. Persistent objects that have been changed within the current transaction are persistent-dirty.
A persistent-dirty object transitions to persistent-deleted it is the parameter of a call to PersistenceManager.deletePersistent.
On transaction commit, the data store record the persistent-dirty instance represents will be updated to reflect the values in the object's persistent fields. The lifecycle state transitions for a persistent-dirty instance on transaction completion are the same as those outlined above for a persistent-clean instance.
Persistent-deleted. If a persistent object is the parameter of a call to the PersistenceManager's deletePersistent method, it becomes persistent-deleted. When an object is in this state, you are only allowed to access its primary key fields. Attempting to access any other persistent field will result in a JDOUserException.
A persistent-deleted object transitions to transient on transaction commit. The data store record for the object is removed. The values of the instance's persistent fields are replaced with Java default values. On transaction rollback, a persistent-deleted object transitions to persistent-nontransactional if the Transaction's RetainValues property is set to true, else it transitions to hollow.
Hollow. Persistent objects whose values have not been loaded from the data store are in the hollow state. Whenever an instance transitions to hollow, its persistent fields are cleared and replaced with their Java default values. The fields will be re-loaded with their data store values the first time you access them. Delaying the loading of persistent information until it is needed is known as lazy loading.
JDO implementations use only weak or soft references to track hollow instances, so they may be garbage collected if your application does not hold strong references to them.
If you are using optimistic transactions, a hollow instance will transition to persistent-nontransactional if any of its persistent, non-primary-key fields are read. Under data store transactions, the instance will transition to persistent-clean. Writing to a persistent field of a hollow instance will cause it to transition to persistent-dirty, regardless of transaction type.
Persistent-nontransactional. Persistent-nontransactional objects represent persistent data in the data store, but are not guaranteed to reflect the most current values of that data. A lifecycle state that allows access to data that may be outdated might sound useless; if they are utilized carefully, however, persistent-nontransactional objects can sometimes offer large performance gains, with little danger of employing stale data in your application.
The persistent-nontransactional state is an optional feature of JDO, and may not be supported in many implementations. It is also by far the most complex lifecycle state. It is governed by the NontransactionalRead, NontransactionalWrite, RetainValues, and Optimistic properties of the Transaction. Implementations may support any or all of these properties. These properties are detailed in the section explaining PersistenceManagerFactory properties.
Outside of a transaction, reading and writing persistent fields of a persistent-nontransactional instance does not result in any state change. Any modifications you make to the instance's persistent fields will be discarded the next time it enters a data store transaction. Within this type of transaction, reading a persistent field of a persistent-nontransactional instance causes a transition to persistent-clean, and writing a persistent field causes a transition to persistent-dirty. Within an optimistic transaction, reading a persistent field of a persistent-nontransactional instance does not change the instance's state; writing a persistent field causes a transition to persistent-dirty.
A persistent-nontransactional object transitions to persistent-clean if it is the parameter of a call to the PersistenceManager's makeTransactional method. It transitions to persistent-deleted if it is the parameter of a call to makeDeleted. It transitions to transient if it is passed to the PersistenceManager's makeTransient method.
Transient-clean. The transient-clean and transient-dirty states are grouped together in the transient-transactional lifecycle category. Transient-transactional objects are not persistent, but their fields recognize transaction boundaries, meaning they can be restored to their previous values when a transaction is rolled back. You can make a transient instance transient-transactional by passing it to the PersistenceManager's makeTransactional method. Some JDO vendors may not support the transient-transactional states; they are an optional feature of the JDO specification.
Transient-transactional objects that have not been changed in the current transaction are transient-clean. A transient-clean object transitions to transient-dirty if any of its persistent or transactional fields are changed within a transaction. It transitions to transient if it is the parameter of a call to PersistenceManager.makeNontransactional.
Transient-dirty. Transient-transactional instances that have been modified in the current transaction are transient-dirty. On transaction completion, a transient-dirty object transitions to transient-clean. If the Transaction is rolled back and its RestoreValues property is true, the persistent and transactional fields of a transient-dirty object will be restored to the values they had when the transaction began.
![]() | Note |
---|---|
Kodo JDO supports all JDO lifecycle states, including all optional states. |
After reviewing the JDO lifecycle states, the purpose of the JDOHelper's lifecycle operations -- isDirty, isTransactional, isPersistent, isNew, isDeleted -- should be clear. Each one tells you whether or not the given persistence-capable instance has a certain property (dirty, transactional, persistent, new, and deleted, respectively), where these properties are determined by the lifecycle state of the instance. In fact, you can calculate the exact state of the instance based on these properties according to the table below. Once again, however, you will rarely worry about the lifecycle state of your persistence-capable objects in practice.