Here is a class using lifecycle annotations:
@Table("discoveries_lifecycle") public class DiscoveryLifeCycle extends Model {
@Id(Generator.AUTO_INCREMENT) public Long id;
@Max(100) public String name;
@PreFetch @PostFetch @PreInsert @PostInsert private void doit1() { System.out.println("Doit1 on object "+this.toString()); }
@PreSave @PostSave @PreUpdate @PostUpdate public void doit2(LifeCyclePhase lcp) { System.out.println("Doit2 for phase "+lcp+ " on object "+this.toString()); }
... }
Lifecycle annotations are not managed by default by Siena. Maybe in the future, it will be the case but till then, you need to activate it manually (not for play-siena which provides a config for this)
// The most simple GAE case:
PersistenceManager pm = new GaePersistenceManager();
pm = new PersistenceManagerLifeCycleWrapper(pm);
pm.init(null);
PersistenceManagerFactory.install(pm, MyModel.class);
Now when you create a new instance of your Model, it will be associated with the PersistenceManagerLifeCycleWrapper which manages your lifecycle annotations.
For the time being, the lifecycle annotations are applied by Siena on the following actions concerning single objects:
- model.get()
- model.insert()
- model.delete()
- model.update()
- model.save() (insert or update)
Note Query actions (fetch/iter…) or Batch actions are not concerned by lifecycle annotations because those actions are not called on a given object and generally return several objects. Nevertheless, in the future, we will see if lifecycle annotations are required for these functions.
The lifecycle annotations are used to annotate some methods of Model class. The method will be called on the current model instance depending on the phase related to the annotation.
There are 2 kinds of annotations:
- @PreXXX is called before action XXX begins.
- @PostXXX is called after action XXX begins.
For each action, there are 2 annotations @Pre/PostXXX so we have 10 annotations:
- @PreFetch / @PostFetch
- @PreInsert / @PostInsert
- @PreDelete / @PostDelete
- @PreUpdate / @PostUpdate
- @PreSave / @PostSave
You can annotate 2 kinds of function with one or more lifecycle annotations:
@PreFetch
@PreInsert
private/public void myFunction() {}
or
@PreFetch
@PreInsert
private/public void myFunction(LifeCyclePhase lcp) {}
LifeCyclePhase gives you the lifecycle phase in which the function is called. It’s an enum defined as following:
public enum LifeCyclePhase {
PRE_FETCH,
POST_FETCH,
PRE_INSERT,
POST_INSERT,
PRE_DELETE,
POST_DELETE,
PRE_UPDATE,
POST_UPDATE,
PRE_SAVE,
POST_SAVE
}
This can be useful to write one single function and do something depending on the phase.
Note In the function you can also access the classical this which is the object for which the method was called .
Note those function calls are synchronous so if you want to perform asynchronous or long duration operations in background, it’s up to you to create your thread or any background job.