Hi Matt,

Keep in mind you are using extra memory with this approach since Cayenne
already has a snapshot of the original values.  (It needs the snapshot data
to do optimistic locking and to only send changed values in an UPDATE
statement.)

mrg


On Fri, Aug 7, 2015 at 11:19 AM, Matt Watson <m...@swarmbox.com> wrote:

> We do this by extending the CayenneDataObject class and introducing a
> HashMap that tracks the original value of the properties that have changed.
> Override the writeProperty/setToOneTarget (we only care about auditing
> attributes and belongsTo relationships.
>
> Then when it comes time to Insert/Update then you can loop over the
> properties you want to “audit” and check if they are modified
> This map gets reset after commits.
>
> protected Map<String,Object> originalPropertyMap = new
> HashMap<String,Object>();
>
> @PostPersist
> @PostUpdate
> public void initializeOriginalPropertyMap() {
>    this.originalPropertyMap.clear();
> }
>
> @Override
> public void writeProperty(String property, Object value) {
>    if (!this.originalPropertyMap.containsKey(property)) {
>       this.originalPropertyMap.put(property, this.readProperty(property));
>    }
>
>    super.writeProperty(property, value);
> }
>
> @Override
> public void setToOneTarget(String relationship,
> org.apache.cayenne.DataObject value, boolean reverse) {
>    if (!this.originalPropertyMap.containsKey(relationship)) {
>       this.originalPropertyMap.put(relationship,
> this.readProperty(relationship));
>    }
>
>    super.setToOneTarget(relationship, value, reverse);
> }
> @Override
>    public Boolean isPropertyModified(String property) {
>       Object original = this.getOriginalProperty(property);
>       Object current = this.readProperty(property);
>
>       // if property is an attribute and array, then use array compares
>       PropertyDescriptor propertyDescriptor = Cayenne.getProperty(this,
> property);
>       if(propertyDescriptor instanceof AttributeProperty) {
>
>  
> if(((AttributeProperty)propertyDescriptor).getAttribute().getJavaClass().isArray())
> {
>             return !Objects.deepEquals(original, current);
>          }
>       }
>
>       return !Objects.equals(original, current);
>    }
>
>
>
> > On Aug 7, 2015, at 7:16 AM, Hugi Thordarson <h...@karlmenn.is> wrote:
> >
> > Hi all.
> >
> > I’m attempting to implement an audit log using Cayenne, automatically
> storing information on modifications alongside every insert, update and
> delete.
> >
> > I’m currently doing this by adding a listener on the DataDomain that
> watches for the lifecycle events PrePersist, PreUpdate and PreRemove, and
> there I log what’s happening with the objects. Works perfectly.
> >
> > One thing I’m wondering though. How can I find what has changed in an
> object in PreUpdate (i.d. when logging modifications)? For those familiar
> with EOF, I do it there by looking at the
> EOEditingContext’s.commitedSnapshotForObject() and comparing the values
> found there with the object’s current values—but I can’t find how to to do
> something similar in Cayenne.
> >
> > Am I maybe going about this in a completely wrong way (and there’s
> perhaps a much better, more Cayenne-ish way to do this)? If so, I’d be
> grateful if someone could point me in the correct direction :).
> >
> > Thanks once again,
> > - hugi
> >
> > // Hugi Thordarson
> > // http://www.loftfar.is/ <http://www.loftfar.is/>
> > // s. 895-6688
>
>

Reply via email to