Я почти уверен, что это невозможно.Механизм аннотированных сущностей очень статичен, поэтому я перестал его использовать.
Вместо этого в аналогичных ситуациях я определил интерфейсы для реализуемых сущностей, что-то вроде этого:
interface UpdateValidation{
void preUpdate();
}
interface PersistValidation{
void prePersist();
}
// etc.
Теперь определите один EntityListener, который проверяет сущности на наличие вышеуказанных интерфейсов.В методе @PreUpdate
проверьте UpdateValidation
, в методе @PrePersist
проверьте PersistValidation
.Затем делегируйте методы объекта.
Таким образом, у вас будет один прослушиватель, который контролирует всю функциональность, и вы можете включить или отключить этот прослушиватель с помощью конфигурации XML.
Обновление Вот полная реализация:
public class DelegatingEntityListener{
public interface PrePersistSupport{
void prePersist();
}
public interface PostPersistSupport{
void postPersist();
}
public interface PreRemoveSupport{
void preRemove();
}
public interface PostRemoveSupport{
void postRemove();
}
public interface PreUpdateSupport{
void preUpdate();
}
public interface PostUpdateSupport{
void postUpdate();
}
public interface PostLoadSupport{
void postLoad();
}
@PrePersist
public void prePersist(final Object entity){
if(entity instanceof PrePersistSupport){
((PrePersistSupport) entity).prePersist();
}
}
@PostPersist
public void postPersist(final Object entity){
if(entity instanceof PostPersistSupport){
((PostPersistSupport) entity).postPersist();
}
}
@PreRemove
public void preRemove(final Object entity){
if(entity instanceof PreRemoveSupport){
((PreRemoveSupport) entity).preRemove();
}
}
@PostRemove
public void postRemove(final Object entity){
if(entity instanceof PostRemoveSupport){
((PostRemoveSupport) entity).postRemove();
}
}
@PreUpdate
public void preUpdate(final Object entity){
if(entity instanceof PreUpdateSupport){
((PreUpdateSupport) entity).preUpdate();
}
}
@PostUpdate
public void postUpdate(final Object entity){
if(entity instanceof PostUpdateSupport){
((PostUpdateSupport) entity).postUpdate();
}
}
@PostLoad
public void postLoad(final Object entity){
if(entity instanceof PostLoadSupport){
((PostLoadSupport) entity).postLoad();
}
}
}
И на случай, если вы удивитесь: нет, я не писал код вручную.Вот код, который написал этот код :-) Вы можете легко настроить его в соответствии со своими потребностями.
public static void main(final String[] args){
final StringBuilder ib = new StringBuilder(); // interface builder
final StringBuilder sb = new StringBuilder(); // method builder
for(final Class<? extends Annotation> annotationType : Arrays
.asList(
// all lifecycle annotations:
PrePersist.class, PostPersist.class, PreRemove.class,
PostRemove.class, PreUpdate.class, PostUpdate.class,
PostLoad.class)){
final String annotationName = annotationType.getSimpleName();
final String lower =
annotationName
.substring(0, 1)
.toLowerCase()
.concat(annotationName.substring(1));
ib.append("public interface ")
.append(annotationName)
.append("Support{\n\tvoid ")
.append(lower)
.append("();\n}\n\n");
sb.append('@')
.append(annotationName)
.append(" public void ")
.append(lower)
.append("(Object entity){\nif(entity instanceof ")
.append(annotationName)
.append("Support){((")
.append(annotationName)
.append("Support)entity).")
.append(lower)
.append("();}}\n\n");
}
System.out.println(ib.toString());
System.out.println(sb.toString());
}
Недостатком является, конечно, то, что провайдер JPA не может кэшировать фактически используемые методы жизненного цикла,но я бы сказал, что это единственный способ получить то, что вы хотите / нужно.