Reputation: 6182
I use Spring Boot, running with v1.5.1.RELEASE, Spring v4.3.6.RELEASE. I am trying to be a bit clever with my JPA event listeners, but it is not working;
My entity looks like this
@Entity
@EntityListeners({MyEntityListener.class})
public class Entity extends SomeOtherEntity implements SomeInterfaceForAudit {
}
My EventListener class looks like this
public class MyEntityListener extends EntityListener<SchoolAdmin> {
// some other useful things in here...
}
My "cleverness" is in that I have tried to "generify" the EntityListener like this;
public abstract class EntityListener {
public abstract class EntityListener<T> {
private Logger logger = LoggerFactory.getLogger(this.getClass());
@PostUpdate
@PostConstruct
@PostRemove
public void queueForIndex(T entity) {
logger.info("queueForIndex " + entity.toString());
}
}
}
There is no logging done. I have tried to create a method like this in my Entity class
@PostUpdate
public void reIndex() {
System.out.println("--- post update-- ---- -<<<--- " + entity);
}
This works. I can't see why my Generified versjon should not work? Anyone?
Upvotes: 0
Views: 1743
Reputation: 606
The correct answer is that when Hibernate fetches the methods from the listener class, it uses getDeclaredMethods()
which doesn't return inherited methods.
You can see in
org.hibernate.jpa.event.internal.CallbackDefinitionResolverLegacyImpl.resolveEntityCallbacks
XClass xListener = reflectionManager.toXClass( listener );
callbacksMethodNames = new ArrayList<>();
List<XMethod> methods = xListener.getDeclaredMethods();
Code from hibernate-core-5.6.15
Upvotes: 0
Reputation: 8396
If you look at the official doc, for the jpa entity life cycle callback annotation, you will see there is no @Inherited
annotation there. This meta-annotation causes annotations to be inherited from superclass. As it is not in these callback method annotations, subclass will be unaware about their presence in the superclass. Exactly that is going on in your case, MyEntityListener.class is getting queueForIndex(T entity) method by inheritence as a normal method, not as a entity life cycle callback method.
Showing only one as example reference: http://docs.oracle.com/javaee/6/api/javax/persistence/PostUpdate.html
@Target(value=METHOD)
@Retention(value=RUNTIME)
public @interface PostUpdate
Upvotes: 2