I don't have an example handy, but IIRC added object is [null, "id"], and removed is ["id", null]. I.e. we don't dump the entire rel state.
Andrus > On Sep 23, 2015, at 11:28 AM, Hugi Thordarson <h...@karlmenn.is> wrote: > > Ah, of course⦠How do you handle a change to a to-many relationship in that > scheme, do oldValue and newValue contain the entire object lists pre- and > post-modification? > > - hugi > > > >> On 23. sep. 2015, at 08:09, Andrus Adamchik <and...@objectstyle.org> wrote: >> >> Just a pair of values: >> >> public class A2PropertyChange { >> >> private Object oldValue; >> private Object newValue; >> >> ... >> } >> >> and as I've shown earlier, my system would emit a stream of JSON messages >> like this: >> >> {"ts":1427090346831,"by":"someuser","clientIP":"10.1.1.1","serverIP":"127.0.0.1","op":"UPDATE","id":"MyEntity:954619","changes":{"email":["r...@example.com","r...@example.org"]}} >> {"ts":1441285381823,"by":"someotheruser","clientIP":"10.1.1.2","serverIP":"127.0.0.1","op":"DELETE","id":"MyOtherEntity:3279984:17","snapshot":{"favorite":true,"sequence":0}} >> >> We'd send them to Apache Kafka, so that other internal apps can process them >> sequentially at their leisure. >> >> Andrus >> >>> On Sep 23, 2015, at 10:55 AM, Hugi Thordarson <h...@karlmenn.is> wrote: >>> >>> This looks really great! Would you mind sharing how the class >>> A2PropertyChange looks? >>> >>> Cheers, >>> - hugi >>> >>> >>> >>>> On 22. sep. 2015, at 19:57, Andrus Adamchik <and...@objectstyle.org> wrote: >>>> >>>> Here is the design of the audit framework for everyone's review: >>>> >>>> https://issues.apache.org/jira/browse/CAY-2030 >>>> >>>> The way it will work from the user perspective is this: >>>> >>>> // bootstrap the filter by adding an extra Cayenne-provided module to >>>> // runtime. Optionally add your own module that overrides context provider >>>> // (e.g. to store request IP address and user name). >>>> ServerRuntime r = ServerRuntimeBuilder.builder().addModule(new >>>> WhateverModuleNameWeUse()).build(); >>>> >>>> // register listener >>>> r.getDataDomain().addListener(new MyListener()); >>>> >>>> >>>> // listener code >>>> class MyListener { >>>> >>>> >>>> @PostCommit >>>> void processAsChangeset(Map<ObjectId, ObjectChangeSet> map) {..} >>>> >>>> // optionally can take a changeset serialized to JSON >>>> @PostCommit >>>> void processAsJSON(Map<ObjectId, String> map) {..} >>>> } >>>> >>>> Andrus >>> >> >