I created a simple project with contains only one Entity which inherits from AbstractAggregateRoot and tries to register an event during the @PrePersist JPA lifecycle event.
@PrePersist
fun addCreatedEvent() {
logger.info("Adding created event for $this")
this.registerEvent(ExampleCreated(this))
}
But when calling the save/saveAndFlush methods on the repository, the event will not be passed on to the EventListener methods on my service.
fun createExample(id: Int, name: String): ExampleEntity{
val entityToSave = ExampleEntity(id, name)
logger.info("saving entity $entityToSave")
val savedEntity = repository.saveAndFlush(entityToSave)
logger.info("saved entity $savedEntity")
return savedEntity
}
The problem seems to be, that the PrePersist method is called on the object instance that is returned from the save method but the domainEvents method is called on the instance that is passed to the save method.
I created a small project to show this problem: https://github.com/thuri/spring-domain-events
I'm not sure whether I'm doing something unintended here or if this is a bug. Would be great if somebody could help me out here.
If there is any other way to create an domain event for "Entity Created" then that may be enough for me.
When doing something similar with @PreRemove the handling seems to work correctly. But that's probably just because the instance passed to the repositorys delete methode is already contained in the persistence context.
UPDATE regarding @PreRemove: there are some cases in which this also won't work. Not sure yet what is the reason there. If I call the service methods from the main method than it doesn' work. If the service get's is own method which calls the methods on it's own it does work. Probably something to to with the @Transactional
UPDATE2 regarding @PreRemove: When the entity is detached/removed from entity manager the PreRemove lifecycle event is called on a new instance that is fetched from DB but the domainEvents method is called on the instance that was passed to the delete method of the repository. So we have a similar problem as with the PrePersist
Finally found a workaround: The issue is the manually assigned Id of the Example Entity.
If the id field is null by default and the value generated by a sequence or other type of Generator then the event is triggered.
If it is necessary to assign the id manually one could implement Persistable and make the entity object itself define whether it's new or not.
Adjusted the example project to see all variants: https://github.com/thuri/spring-domain-events/commit/097904594f6cd83526b871d0599fd04e13a6cc0c