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