Hi Matt, Cayenne already keeps track of the original values for you. This is needed in order to do optimistic locking, plus it allows Cayenne to only send over changes in a record instead of the entire record when you are doing an UPDATE.
I haven't tried this approach on the field-based version of Cayenne yet, but these two utility methods are similar and illustrate how to find the underlying values and detect the changes, at least in 3.x: https://gist.github.com/mrg/4dce22b67175c27f4047#file-cayenneutils-java-L124 https://gist.github.com/mrg/4dce22b67175c27f4047#file-cayenneutils-java-L184 I believe you could adapt for your purposes/needs pretty readily. mrg On Mon, Sep 10, 2018 at 8:04 PM Matt R Watson <[email protected]> wrote: > Now that the DataObject classes are “field based”, I would like to find a > way to replace the heavy Map we have placed on all of our DataObject > classes. > > We extend Cayenne’s default class and added a HashMap to keep track of the > original values (as it changes) since the object has been loaded and before > committing. (see our class below) > > This allows us to check if something is modified ( > inventoryAdjustment.isPropertyModified(“date”), or > inventoryAdjustment.getOriginalProperty(“date”) ) > > I’d like to find a Cayenne friendly way of doing this. Any suggestions? > > Thanks, > Matt > > ---------------------------------------------------- > > > public class CayenneBaseDataObject extends CayenneDataObject { > > /** > * Stores the original values for this object's properties. Uses > the > * property name string as the key for each entry. Its purpose is > to keep > * track of any original values since the object was initialized > or last > * committed. > */ > private final Map<String,Object> originalPropertyMap = New.map(); > > /** > * Initializes the originalPropertyMap. Used as a callback during > the > */ > public void initializeOriginalPropertyMap() { > originalPropertyMap.clear(); > } > > @Override > protected void beforePropertyWrite(String propName, Object oldValue, > Object newValue) { > if (!originalPropertyMap.containsKey(propName)) { > originalPropertyMap.put(propName, oldValue); > } > > super.beforePropertyWrite(propName, oldValue, newValue); > } > > /** > * Overrides > * {@link org.apache.cayenne.DataObject#writeProperty(String, > Object)} by > * saving a {@link CayenneBaseDataObject}'s existing property > value, if any, > * to the {@link #originalPropertyMap} prior to updating the > * {@link CayenneBaseDataObject}'s property with a new value. > * > * @param relationship > * the name of the to-one-relationship > * @param value > * the value used to set the to-one-relationship > * @param reverse > * a boolean indicating whether to set the reverse > relationship as well > */ > @Override > public void setToOneTarget(final String relationship, final > org.apache.cayenne.DataObject value, final boolean reverse) { > if (!originalPropertyMap.containsKey(relationship)) { > originalPropertyMap.put(relationship, > this.readProperty(relationship)); > } > > super.setToOneTarget(relationship, value, reverse); > } > > > @Override > public Object getOriginalProperty(final String property) { > if (!originalPropertyMap.containsKey(property)) { > return this.readProperty(property); > } > > return originalPropertyMap.get(property); > } > > @Override > public Boolean isPropertyModified(final String property) { > final Object original = this.getOriginalProperty(property); > final Object current = this.readProperty(property); > > return !Objects.equals(original, current); > } > > } > >
