Chaining EntityChangedEvent listeners call

Hi,

It seems there is a limitation in calling a sequence of EntityChangedEvent listeners, only the first one is called.

Given entities and listeners:

Product

Movement : stock movement for a given Product and quantity

Stock
  • quantity : total product quantity
  • lastMoveQuantity : record last quantity of the last move occured

MovementListener : update total product quantity on Stock through a service call

StockListener : update Stock last move quantity through a service call

1st execution flow, update stock directly : create Stock, save it, StockListener.beforeCommit was called

2nd execution flow, update Movement, which updates Stock total quantity, which does not update Stock last move quantity, because StockListener.beforeCommit was not called.

Does it mean that once you are in an execution flow of a beforeCommit method of a transactional listener, you cannot reach other beforeCommit methods of other transactional listeners ?

Sample project attached with 2 integration tests for each execution flow, 1st one succeeds, 2nd one fails.

Any help appreciated.

Regards,
Michael

EDIT : tested also with afterCommit as a workaround, but no luck either, which seems logical

tranlist.zip (82.4 KB)

Hi Michael,

Chaining will work and your test will pass if you use @EventListener annotation instead of @TransactionalEventListener(phase = TransactionPhase.BEFORE_COMMIT). It is semantically the same (handling the event in the current transaction), but the inner working is slightly different.

For example:

@EventListener
public void beforeCommit(EntityChangedEvent<Movement, UUID> event) {
}

Perhaps we need to change CUBA docs in this part and recommend using @EventListener, as we do in Jmix docs. Thanks for pointing out the issue!

Hi @krivopustov

Thank you. I must admit I was completely puzzled, so I scrutinized my code very carefully, and even debugged the listeners mechanism. But this is fairly complex, so I finally changed my code in order to avoid chaining the beforeCommit listeners (because in that particular case, I could do so).

That’s good to know for the rest. And I follow you on the documentation update. Whatever the mechanism used, I think that developers expect it to work like triggers work in database.

NB : I checked that the problem does not happen while using entity listeners instead of transaction listeners. But the application is using quite a lot of transaction listeners already, and by experience it’s not good to mix both (you may possibily have different views on that).

Michael