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); >>>>> } >>>>> >>>>> } >>>>> >>>>> >>> >>>