JDO 2.0 defines an interface for the PersistenceManager and PersistenceManagerFactory whereby a user can register a
listener for persistence events. The user provides a listener for either all classes, or a set of defined classes,
and the JDO implementation calls methods on the listener when the required events occur. This provides the user
application with the power to monitor the persistence process and, where necessary, append related behaviour.
Specifying the listeners on the PersistenceManagerFactory has the benefits that these listeners will be added
to all PersistenceManagers created by that factory, and so is for convenience really. This facility is a complement
to the Instance Callbacks facility which allows interception of events on
an instance by instance basis. The
Lifecycle Listener
process is much less intrusive than the
process provided by
Instance Callbacks
, allowing a class external to the persistence process to perform
the listening.
DataNucleus supports the
InstanceLifecycleListener
interface.
.
To give an example of this capability, let us define a Listener for our persistence process.
public class LoggingLifecycleListener implements CreateLifecycleListener,
DeleteLifecycleListener, LoadLifecycleListener, StoreLifecycleListener
{
public void postCreate(InstanceLifecycleEvent event)
{
log.info("Lifecycle : create for " +
((PersistenceCapable)event.getSource()).jdoGetObjectId());
}
public void preDelete(InstanceLifecycleEvent event)
{
log.info("Lifecycle : preDelete for " +
((PersistenceCapable)event.getSource()).jdoGetObjectId());
}
public void postDelete(InstanceLifecycleEvent event)
{
log.info("Lifecycle : postDelete for " +
((PersistenceCapable)event.getSource()).jdoGetObjectId());
}
public void postLoad(InstanceLifecycleEvent event)
{
log.info("Lifecycle : load for " +
((PersistenceCapable)event.getSource()).jdoGetObjectId());
}
public void preStore(InstanceLifecycleEvent event)
{
log.info("Lifecycle : preStore for " +
((PersistenceCapable)event.getSource()).jdoGetObjectId());
}
public void postStore(InstanceLifecycleEvent event)
{
log.info("Lifecycle : postStore for " +
((PersistenceCapable)event.getSource()).jdoGetObjectId());
}
}
Here we've provided a listener to receive events for CREATE, DELETE, LOAD, and STORE of objects. These
are the main event types and in our simple case above we will simply log the event. All that remains
is for us to register this listener with the PersistenceManager, or PersistenceManagerFactory
pm.addInstanceLifecycleListener(new LoggingLifecycleListener(), null);
When using this interface the user should always remember that the listener is called within the same
transaction as the operation being reported and so any changes they then make to the objects in
question will be reflected in that objects state.
Register the listener with the PersistenceManager or PersistenceManagerFactory provide different effects.
Registering with the PersistenceManagerFactory means that all PersistenceManagers created by it will
have the listeners registered on the PersistenceManagerFactory called. Registering the listener with the
PersistenceManager will only have the listener called only on events raised only by the PersistenceManager
instance.
The above diagram displays the sequence of actions for a listener registered only in the PersistenceManager.
Note that a second PersistenceManager will not make calls to the listener registered in the first
PersistenceManager.
The above diagram displays the sequence of actions for a listener registered in the PersistenceManagerFactory.
All events raised in a PersistenceManager obtained from the PersistenceManagerFactory will make calls to
the listener registered in the PersistenceManagerFactory.
DataNucleus supports the following instance lifecycle listener types
-
AttachLifecycleListener
- all attach events
-
ClearLifecycleListener
- all clear events
-
CreateLifecycelListener
- all object create events
-
DeleteLifecycleListener
- all object delete events
-
DetachLifecycleListener
- all detach events
-
DirtyLifecycleListener
- all dirty events
-
LoadLifecycleListener
- all load events
-
StoreLifecycleListener
- all store events
The default JDO2 lifecycle listener
StoreLifecycleListener
only informs the listener of the
object being stored. It doesn't provide information about the fields being stored in that event.
DataNucleus extends the JDO2 specification and on the "preStore" event it will return an instance of
org.datanucleus.FieldInstanceLifecycleEvent
(which extends the JDO2 InstanceLifecycleEvent) and provides
access to the names of the fields being stored.
public class FieldInstanceLifecycleEvent extends InstanceLifecycleEvent
{
...
/**
* Accessor for the field names affected by this event
* @return The field names
*/
public String[] getFieldNames()
...
}
If the store event is the persistence of the object then this will return all field names. If instead
just particular fields are being stored then you just receive those fields in the event. So the only thing
to do to utilise this DataNucleus extension is cast the received event to
org.datanucleus.FieldInstanceLifecycleEvent