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