Hi Matt, Sorry for delayed reply.
So you have a case that I call "an aggregate" - a root object and its closely-related children. And it has to be processed only once during any given commit, even though multiple objects may have changed. We have a good example of that in Cayenne. Take a look at AuditableFilter [1] located in cayenne-lifecycle module. To define an aggregate for the audit operation it uses 2 annotations on DataObjects - @Auditable and @AuditableChild [2]. AuditableFilter itself defines a number of listener methods that are invoked in the context of a transaction when an annotated entity is modified. Instead of invoking an action immediately, the filter would combine the events together by the root of an aggregate. You may write a similar filter for your case. You don't have to use @Auditable / @AuditableChild. Instead you would annotate the listener methods with @PostUpdate(SalesOrder.class) and @PostUpdate(SalesOrderLine.class)), etc. But you can use the same general approach. Hope this helps, and please ask if anything is unclear in the AuditableFilter. Andrus [1] https://github.com/apache/cayenne/blob/master/cayenne-lifecycle/src/main/java/org/apache/cayenne/lifecycle/audit/AuditableFilter.java [2] https://github.com/apache/cayenne/tree/master/cayenne-lifecycle/src/main/java/org/apache/cayenne/lifecycle/audit > On Sep 15, 2015, at 2:50 AM, Matt Watson <m...@swarmbox.com> wrote: > > I was curious about what you could accomplish with EventManager listeners. > > I have a scenario where I normally use the Cayenne lifecycle callbacks to > detect when an Object was updated, and “sync” it to an external system. > > class SalesOrder { > void sync() { > // send data to external system > } > > @PostUpdate > void didUpdate() { > this.sync(); > } > } > > > But I now want to sync a SalesOrder if it changes or if any of its > SalesOrderLines (many relationship) change. But If both objects > SalesOrder/SalesOrderLine are part of the same commit, then I don’t want the > sync to get invoked more than once. > > If I just used the logic below, its possible that the SalesOrder would get > synced multiple times for all of its child SalesOrderLines, and possibly > again if the SalesOrder itself changes > > class SalesOrderLine { > @PostUpdate > void didUpdate() { > this.getSalesOrder().sync(); > } > } > > Was hoping to find something that I can execute after the commit of all > objects is done, but call sync on the SalesOrder once. Can the EventManager > help with this? > > post-commit listeners? > > Thanks, > > Matt Watson