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 <[email protected]> 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