I don't really know the answer to your questions. My uncertainty is
part of the reason I'd avoid changing the state.
On the other hand, you might be fixing a bug or at least performance
issue in the code :)
On 8/26/05, Sean Tan <sabrebox2000-cod..ahoo.com.sg> wrote:
> Hmm, but in doing so, the PersistenceState will become MODIFIED whenever
> a single setter is invoked... I'm not sure whether this is the original
> intention, but I felt it will be more intuitive that it reflects an
> actual change in value.
>
> Did I again missed out something that will break the code?
>
> Just a side note, I have noticed that DataContext.commitChanges() relies
> on ObjectStore.hasChanges() which checks for the the
> PersistenceState.MODIFIED. When a DataObject is in this state, there
> will be iteration to check for modified fields. Thus perhaps by making
> the PersistenceState to be MODIFIED only when there is an actual change
> in value could constitue a minor improvement in speed when there is a
> large number of unchanged DataObject with PersistenceState.MODIFIED?
> This is just a wild guess since I have not done any profiling in Cayenne
> before.
>
>
> Mike Kienenberger wrote:
>
> >If it were me, I'd still add a check in validateForSave() to make sure
> >that the current valuees being committed were different from the
> >cached snapshot, and I wouldn't try to modify the persistence state in
> >writeProperty.
> >
> >
> >
> >On 8/26/05, Sean Tan <sabrebox2000-cod..ahoo.com.sg> wrote:
> >
> >
> >>Thanks alot for pointing that out Mike! I missed out the problem.
> >>
> >>I have taken your suggestion and Andrus to implement my solution.
> >>
> >>I have included the code here for completeness sake of the discussion.
> >>-----
> >>public class MyCayenneDataObject extends
> >>org.objectstyle.cayenne.CayenneDataObject {
> >>
> >> public void writeProperty(String propName, Object val) {
> >> resolveFault();
> >>
> >> // 1. retain object snapshot to allow clean changes tracking
> >> // 2. change object state
> >> if (persistenceState == PersistenceState.COMMITTED) {
> >> DataRow committedSnapshot =
> >>dataContext.getObjectStore().getCachedSnapshot(getObjectId());
> >> boolean modified = false;
> >> if (committedSnapshot == null) {
> >> modified = true;
> >> } else {
> >> Object oldValue = committedSnapshot.get(propName);
> >> modified = !Util.nullSafeEquals(oldValue, val);
> >> }
> >> if (modified) {
> >> persistenceState = PersistenceState.MODIFIED;
> >> dataContext.getObjectStore().retainSnapshot(this);
> >> }
> >> }
> >> // else....
> >> // other persistence states can't be changed to MODIFIED
> >>
> >> writePropertyDirectly(propName, val);
> >> }
> >>
> >>}
> >>-----
> >> protected void validateForSave(ValidationResult validationResult) {
> >> setTimestamp(new Date(System.currentTimeMillis()));
> >> super.validateForSave(validationResult);
> >> }
> >>-----
> >>
> >>Sean
> >>
> >>Mike Kienenberger wrote:
> >>
> >>
> >>
> >>>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
> >>>>
> >>>>
> >>>>
> >>>>
> >>>>
> >>>>
> >>>
> >>>
> >>>
> >>Send instant messages to your online friends http://asia.messenger.yahoo.com
> >>
> >>
> >>
> >>
> >
> >
> >
> 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 - 12:02:06 EDT