Re: PersistenceState relation to property changes

From: Mike Kienenberger (mkienen..mail.com)
Date: Fri Aug 26 2005 - 10:18:03 EDT

  • Next message: Sean Tan: "`"

    The problem with doing it with writeProperty() is that it won't detect
    differences in this situation:

    obj.getField() == 1

    obj.setField(0);
    obj.setField(1);
    obj.getDataContext().commit;

    However, as Andrus states, if you want to do this, it's trivial to
    handle this in a base DataObject superclass.

    (In fact, I override writeObject in a base DataObject superclass to
    change empty strings to null since Oracle doesn't handle empty
    strings.

    If you're willing to dig into the advanced parts of Cayenne a little
    more, you can use the same logic that Cayenne uses for determining
    which objects have changed fields in validate*.

    You'd just compare the current value snapshots with the original
    object snapshots.

    On 8/26/05, Sean Tan <sabrebox2000-cod..ahoo.com.sg> wrote:
    > Thanks a lot for very quick reply Andrus! =)
    > Hmm.... I tried your suggestion but notice the follow things:
    > 1. Cayenne relies on DataContext.hasChanges() to know whether there is
    > any real modifications. But this only allows Cayenne to know whether
    > there are any modifications within the DataContext, not based on
    > individual DataObjects.
    > 2. Due to the above, once there is a single modified DataObject within
    > the DataContext, the validate* methods will be called for all
    > DataObjects marked modified.
    >
    > As such, I think your suggestion does not work.
    >
    > I'm not sure how useful will it be to the rest of the users, but I guess
    > having the PersistenceState.MODIFIED to reflect real modifications are
    > intuitive and useful in most cases. Or perhaps we can have an option to
    > turn it On/Off....
    >
    > On the same line, perhaps out-of-the-box Cayenne could support the use
    > of fields like TimeStamp, as it would help alot in users who are
    > re-engineering from existing DB systems which relies on this feature.
    >
    > --
    > Sean
    >
    > Andrus Adamchik wrote:
    >
    > > Hi there,
    > >
    > > Your solution will work and you can put your overridden
    > > "writeProperty" in your own custom superclass of DataObjects thus
    > > changing default Cayenne behavior.
    > >
    > > Here is another solution however - override "validateForSave" to add
    > > your timestamp logic:
    > >
    > > http://objectstyle.org/cayenne/userguide/dataobjects/validation.html
    > >
    > > See, even if an object is marked as modified on "setXYZ" call when
    > > there was no real modification, this fact will be detected by Cayenne
    > > later on commit, and the object will not be committed, and its
    > > validate* methods won't be called.
    > >
    > > Hope this helps.
    > >
    > > Andrus
    > >
    > > On Aug 26, 2005, at 2:03 PM, Sean Tan wrote:
    > >
    > >> I'm attempting to use Cayenne v1.1.2 with the idea of having a field
    > >> that mimics the behavior of MySql's TimeStamp dbtype.
    > >>
    > >> The timestamp will only update if at least a change is detected in the
    > >> rest of the columns.
    > >>
    > >> I'm trying to rely on the PersistenceState of CayenneDataObject but I
    > >> realized that the PersistenceState is set to Modified even when the new
    > >> value being introduced is the same as the old value. This poses a
    > >> problem, especially in the context of webframeworks like Tapestry which
    > >> all bounded fields will be updated, meaning the writeProperty(String
    > >> propName, Object val) of the CayenneDataObject will always be
    > >> called....
    > >> PersistenceState being set to Modified although no change is made.
    > >>
    > >> One usage scenario is when you create a HTML table of records which
    > >> allows the user to change the records inline, and click on a update
    > >> button.
    > >>
    > >> Thus, I'm proposing that perhaps the writeProperty method could be
    > >> adjusted to do additional check as below to suit this purpose.
    > >> ----
    > >> public void writeProperty(String propName, Object val) {
    > >> resolveFault();
    > >>
    > >> // 1. retain object snapshot to allow clean changes tracking
    > >> // 2. change object state
    > >> Object oldVal = readPropertyDirectly(propName);
    > >> if (persistenceState == PersistenceState.COMMITTED &&
    > >> oldVal.equals(val) == false) {
    > >> persistenceState = PersistenceState.MODIFIED;
    > >> dataContext.getObjectStore().retainSnapshot(this);
    > >> }
    > >> // else....
    > >> // other persistence states can't be changed to MODIFIED
    > >>
    > >> writePropertyDirectly(propName, val);
    > >> }
    > >> -----
    > >>
    > >> Or am I missing out a better way to do this?
    > >>
    > >> --
    > >> Sean Tan
    > >
    > >
    > >
    >
    >
    > Send instant messages to your online friends http://asia.messenger.yahoo.com
    >
    >



    This archive was generated by hypermail 2.0.0 : Fri Aug 26 2005 - 10:18:05 EDT