Skip to content

Instantly share code, notes, and snippets.

@domdorn
Created January 1, 2012 12:46
Show Gist options
  • Star 8 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save domdorn/1547244 to your computer and use it in GitHub Desktop.
Save domdorn/1547244 to your computer and use it in GitHub Desktop.
JPA2 EntityListener Annotations for EBean
package models.sgcore;
import com.avaje.ebean.event.BeanPersistAdapter;
import com.avaje.ebean.event.BeanPersistRequest;
import javax.annotation.PreDestroy;
import javax.persistence.*;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
/**
* This is a <code>BeanPersistController</code> that looks for methods annotated with the JPA Annotations
* <code>@PrePersist</code>
* <code>@PostPersist</code>
* <code>@PreUpdate</code>
* <code>@PostUpdate</code>
* <code>@PreDestroy</code>
* <code>@PostLoad</code>
*
* registers those methods with this Listener and calls them when necessary.
*/
public class SGBeanPersistController extends BeanPersistAdapter {
private Map<String,Method> prePersistMap = new TreeMap<String, Method>();
private Map<String,Method> postPersistMap = new TreeMap<String, Method>();
private Map<String,Method> preUpdateMap = new TreeMap<String, Method>();
private Map<String,Method> postUpdateMap = new TreeMap<String, Method>();
private Map<String,Method> preDestroyMap = new TreeMap<String, Method>();
private Map<String,Method> postLoadMap = new TreeMap<String, Method>();
@Override
public boolean isRegisterFor(Class<?> aClass) {
if(aClass.getAnnotation(Entity.class) != null){
System.out.println("Registering a Entity; Type is " + aClass.toString());
Method[] methods = aClass.getMethods();
boolean hasListener = false;
for(Method m : methods)
{
// System.out.println("looking if method " + m.toString() + " has Annotation on it. ");
if(m.isAnnotationPresent(PrePersist.class))
{
prePersistMap.put(aClass.getName(), m);
hasListener = true;
}
if(m.isAnnotationPresent(PostPersist.class))
{
postPersistMap.put(aClass.getName(), m);
hasListener = true;
}
if(m.isAnnotationPresent(PreDestroy.class))
{
preDestroyMap.put(aClass.getName(), m);
hasListener = true;
}
if(m.isAnnotationPresent(PreUpdate.class))
{
preUpdateMap.put(aClass.getName(), m);
hasListener = true;
}
if(m.isAnnotationPresent(PostUpdate.class))
{
postUpdateMap.put(aClass.getName(), m);
hasListener = true;
}
if(m.isAnnotationPresent(PostLoad.class))
{
postLoadMap.put(aClass.getName(), m);
hasListener = true;
}
}
return hasListener;
}
return false;
}
private void getAndInvokeMethod(Map<String,Method> map, Object o)
{
Method m = map.get(o.getClass().getName());
if(m != null)
try {
m.invoke(o);
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
@Override
public boolean preInsert(BeanPersistRequest<?> request) {
getAndInvokeMethod(prePersistMap, request.getBean());
return super.preInsert(request);
}
@Override
public boolean preDelete(BeanPersistRequest<?> request) {
getAndInvokeMethod(preDestroyMap, request.getBean());
return super.preDelete(request);
}
@Override
public boolean preUpdate(BeanPersistRequest<?> request) {
getAndInvokeMethod(preUpdateMap, request.getBean());
return super.preUpdate(request);
}
@Override
public void postDelete(BeanPersistRequest<?> request) {
// there is no @PostDestroy annotation in JPA 2
super.postDelete(request);
}
@Override
public void postInsert(BeanPersistRequest<?> request) {
getAndInvokeMethod(postPersistMap, request.getBean());
super.postInsert(request);
}
@Override
public void postUpdate(BeanPersistRequest<?> request) {
getAndInvokeMethod(postUpdateMap, request.getBean());
super.postUpdate(request);
}
@Override
public void postLoad(Object bean, Set<String> includedProperties) {
getAndInvokeMethod(postLoadMap, bean);
super.postLoad(bean, includedProperties);
}
}
@gyorn
Copy link

gyorn commented Apr 8, 2012

Verry helpfull indeed ! But you can have only one annoted method of each type in each model.
We should be able to have for example 2 @PostLoad methods in the same model, wich is often the case. Just added a methods list map instead of a methods map.

@sakti
Copy link

sakti commented Aug 22, 2012

Thank you

@iXo
Copy link

iXo commented May 3, 2013

Great job ! I have created a fork beacause ebean entity bean class names contains some extra preventing to invoke postUpdate method (was unable to find the key for the method).

@lln78
Copy link

lln78 commented Feb 21, 2014

Firstly thanks !

And just a question : is there a reason to choose the PreDestroy annotation instead of PreRemove (and so PostRemove could be also used) ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment