Thanks mrg.

I am aware that Cayenne knows about the original values, but trying to find an 
efficient way to access them. Or at least more efficient than the Map we are 
currently using, which is heavy on memory yet quick on access time (and easy to 
read code). I’ve seen your utilities in the past when searching for a solution 
for this, but I don’t see anything thats comparable to finding the original 
value of a specific property on a specific object. I also don’t see where you 
are grabbing the original value of a relationship. I know the snapshot can show 
me the original DataRow values, but I don’t think those are always the same 
“type” as the actual DataObject properties.

Still hoping for solution for our current code (that doesn’t have to loop over 
all modified objects, every time):

inventoryAdjustment.isPropertyModified(“date”)
inventoryAdjustment.getOriginalProperty(“date”)

with something like:

Cayenne.isPropertyModified(inventoryAdjustment, "date”)
Cayenne.getOriginalProperty(inventoryAdjustment, "date”)

Thanks,
Matt

> On Sep 11, 2018, at 5:31 AM, Michael Gentry <blackn...@gmail.com> wrote:
> 
> 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 <m...@swarmbox.com> 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);
>>        }
>> 
>> }
>> 
>> 

Reply via email to