When testing your JPA entity handling code with a real entity manager it will not only write your entities to a real database, it will also call all entity listeners you have defined. Your entity listeners might be easy to fix but sometimes it’s just better to remove the entity listeners from the entity manager so they are ignored.
Entity listeners are methods in the entity class annotated with special annotation (such as @PerPersist
or @PostDelete
), or they can be defined in custom classes which are associated with the entity using the @EntityListeners
annotation on the entity itself.
Depending on your entity listeners it can be advantageous to disable all entity listeners during tests instead of trying to get them to run during tests; they might access singletons or frameworks that are not active during tests, and mocking or stubbing those would seriously distract from the test itself.
How entity listeners are created from annotations and exposed via the EntityManager API is not very well specified in JPA; as a result, different JPA providers require different methods to programmatically modify the registered listeners on an entity manager instance.
With Hibernate you can access the entity listeners using the following piece of (Kotlin) code:
private fun removeEntityListeners(entityManager: EntityManager) {
entityManager.entityManagerFactory.unwrap(SessionFactoryImpl::class.java)
.serviceRegistry.locateServiceBinding(EventListenerRegistry::class.java)
.service.run {
getEventListenerGroup(EventType.PRE_INSERT).clear()
getEventListenerGroup(EventType.POST_INSERT).clear()
// repeat for every event type you want to remove
}
}
Removing the entity listeners from the entity manager instance is an easy fix if your tests are a bit too invasive, and it can be omitted for cases when you actually want to execute the entity listeners.