Permalink
Fetching contributors…
Cannot retrieve contributors at this time
129 lines (87 sloc) 3.65 KB

Using Lifecycle Annotations in Siena

Code sample

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());
	}

	...
}

Activating Lifecyle Persistence Manager

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)

Create a normal persistence manager

// The most simple GAE case:
PersistenceManager pm = new GaePersistenceManager();

Wrap it into a PersistenceManagerLifeCycleWrapper and init it

pm = new PersistenceManagerLifeCycleWrapper(pm);
pm.init(null);

Install the PersistenceManagerLifeCycleWrapper into PersistenceManagerFactory for your class

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.


Lifecycle Actions

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.


Lifecycle Annotations

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


Annotating a method

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.