Users can register callback methods that will be invoked during the lifecycle of persistent objects. Callback mechanism is similar to the one defined in the JPA Specification, however there are some noteable differences introduced to better follow the Cayenne object lifecycle. There are eight lifecycle callbacks described below (PostAdd, PrePersist, PostPersist, PreUpdate, PostUpdate, PreRemove, PostRemove, PostLoad). Each one cab be invoked as a callback on a persistent object itself or as a callback on an arbitrary listener object.
|Callbacks feature supercedes the following 1.2/2.0 features:|
- No formal interface is required to mark a method to be used for callback (although org.apache.cayenne.LifecycleListener can optionally be implemented for type-safety and to simplify registration).
- A callback method signature looks like "void someMethod()" for persistent classes.
- It looks like "void method(Type entityObject)" for listener classes.
- A callback method can have an arbitrary name.
- A callback method can use public, private, protected or default access.
- It must NOT be static.
- Callback methods are polymorphic - registering a callback on a superclass (even if the superclass does not map to an entity) will ensure the callback will be invoked on all entity subclasses, using the overriding subclass method if applicable.
Callback on persistent object example:
Callback on a listener class example:
Valid callback types are defined as Java enumerated constants in the org.apache.cayenne.map.LifecycleEvent enumeration.
|PostAdd||Within "ObjectContext.newObject()" after ObjectId and ObjectContext are set.|
|PrePersist||Prior to commit (and prior to "validateFor*") within "ObjectContext.commitChanges()" and "ObjectContext.commitChangesToParent()"|
|PreRemove||Before an object is deleted inside "ObjectContext.deleteObject()"; also includes all objects that will be deleted as a result of CASCADE delete rule.|
|PreUpdate||Prior to commit (and prior to "validateFor*") within "ObjectContext.commitChanges()" and "ObjectContext.commitChangesToParent()"|
|PostPersist||Within "ObjectContext.commitChanges()", after commit of a new object is done.|
|PostRemove||Within "ObjectContext.commitChanges()", after commit of a deleted object is done.|
|PostUpdate||Within "ObjectContext.commitChanges()", after commit of a modified object is done.|
Normally listeners and persistent object callbacks are mapped in the Modeler, but this can also be done in the code. Callbacks are registered with LifecycleCallbackRegistry, which is shared by all contexts within a DataDomain.
Obtaining the shared registry instance:
Registry obtained this way already contains callbacks mapped in the DataMap. To add extra callbacks in runtimes, use various addListener(...) methods.
Adding a listener object that implements LifecycleListener interface:
Adding a listener of an arbitrary class
Finally a persistent object can implement callbacks as well, being notified of its own events: