Aggregate root is saved but domain events is not published, if uses transaction and do not explicitly call "save" [DATAJPA-1412]
See original GitHub issueteclxl opened DATAJPA-1412 and commented
Issue
If it uses @DomainEvent
for publishing domain events, it only executes publishing when the method like “CrudRepository#save*” was calling.This is perfect for persistence-oriented repository, but not for collection-oriented repository, because of we usually don’t call “save” when using collection-oriented repository.
Unfortunately, JPA & Hibernate is collection-oriented.
Possible solution
I found a blog that mentions the issue. It provides solution, but I don’t know if it works. The blog is:
https://blog.pchudzik.com/201710/domain-events/
Another question for @DomainEvents
How can I use @DomainEvents
, if I just want to publish event ,ant don’t want to persist the aggregate root. A detailed description of the questionis here: https://stackoverflow.com/questions/51998921
My Test Code
version is :2.0.7
// Method in aggregate root
public void demoOne() {
registerEvent(new StudentDemoOneEvent(id));
}
// Listener
@TransactionalEventListener
public void demoOne(StudentDemoOneEvent event) {
log.info("DemoOne listener executed! Student id is: " + event.getStudentId().getUuid());
dummyService.exe();
}
// Junit Test
@Test
@Transactional
public final void testDemoOne_allSuccess() {
String newName = "testDemoOne_allSuccess";
TestTransaction.flagForCommit();
StudentAtDb student = repo.findById(STUDENT_ID).get();
student.setName(newName);
student.demoOne();
// repo.save(student);
// if call save, saved and listenered. if not call, saved but not listenered.
TestTransaction.end();
assertEquals(repo.findById(STUDENT_ID).get().getName(), newName);
assertThat(capture.toString(), containsString("DemoOne listener executed!"));
}
Affects: 2.0.9 (Kay SR9)
Issue Analytics
- State:
- Created 5 years ago
- Reactions:1
- Comments:6
teclxl commented
Jens SchauderI am very sorry to did not pay attention to this issue later.
My current solution is to force that the save method must be explicitly called at the end of the service. I used a Hibernate interceptor that was inserted into the
preFlush
, which throws an exception when it finds that the aggregate has some domain events.I found that the issue has become resolved. Can I ask if it is solved or not a problem?
Also, I can’t seem to close the issue, please close it
Jens Schauder commented
Thanks for letting us know about the solution you ended up using teclxl. I like the idea of checking in a listener if an aggregate has still events stored