Glenn Bech
Glenn Bech

Reputation: 6182

JPA EventListeners not working

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

Answers (2)

ladorm
ladorm

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

Monzurul Shimul
Monzurul Shimul

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

Related Questions