True, thanks for the suggestions John. I agree with your assessment of code 
costs vs memories costs

> On Sep 12, 2018, at 2:42 PM, John Huss <johnth...@gmail.com> wrote:
> 
> Or I suppose you could create fields for each of the original values in the
> same way that the current values are stored.
> 
> On Wed, Sep 12, 2018 at 4:32 PM John Huss <johnth...@gmail.com> wrote:
> 
>> Cayenne stores the original values, but they are in DbEntity
>> representation rather than ObjEntity representation which makes comparing
>> the two difficult. Without writing a lot of code to convert and compare
>> your best bet would be to use a more efficient data structure without any
>> extra unneeded space. That would be an array (Object[]) that is smart
>> enough to map a fixed set of string keys into array indexes. To do this
>> you'll need a HashMap<String, Integer> per ObjEntity(table) that maps from
>> string key to array index. Then all of your CayenneDataObjects will need an
>> Object[] with the original values.
>> 
>> On Tue, Sep 11, 2018 at 10:58 AM Matt R Watson <m...@swarmbox.com> wrote:
>> 
>>> 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