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

Reply via email to