RE: Flattened Relationship Insert Problem

From: Scott Finnerty (scot..odefuey.com)
Date: Tue Jul 29 2003 - 14:46:25 EDT


I made the change I described to DataContext.hasChanges() and it solved
the problem. No one has commented on whether it is the right place to
solve this issue of transactions consisting only of flattened
relationship modifications not working.

Scott

-----Original Message-----
From: Scott Finnerty [mailto:scot..odefuey.com]
Sent: Sunday, July 27, 2003 12:54 PM
To: cayenne-deve..bjectstyle.org
Subject: Flattened Relationship Insert Problem

I think this may be the same problem reported by David Benoff on the
user list:
http://objectstyle.org/cayenne/lists/cayenne-user/2003/06/0038.html

If the only change to the current DataContext is the addition of a
flattened relationship at the time a commit is called for, the logic in
DataContext.commitChanges(Level), et al, doesn't see any change and does
nothing.

In DataContext.commitChanges(Level) it checks to see if the DataContext
has any changes, if not it just returns. Drilling down into
ObjectStore.hasChanges() (called by DataContext.hasChanges()) the
problem seems to be in QueryUtils.updatedProperties(DataObject). I can
see the objects on both ends of the flattened relationship have a
persistence state of MODIFIED, so next is that call to
QueryUtils.updatedProperties(DataObject).

After stepping through the code the snapshot comparison (between the
committed and the current) doesn't produce any differences because the
difference is in a relationship - and relationships don't seem to be
reflected in snapshots.

Despite tracing the problem, I feel like I don't have enough knowledge
about this portion of cayenne to make the right fix. I'm thinking
changing QueryUtils.updatedProperties(DataObject) to look for updated
relationships might have undesirable side-effects. So I'd probably look
for some way of changing the following to include a check for updated
relationships:

In org.objectstyle.cayenne.access.ObjectStore.hasChanges():

215 public synchronized boolean hasChanges() {
        Iterator it = objectMap.values().iterator();
        while (it.hasNext()) {
            DataObject dobj = (DataObject) it.next();
            int state = dobj.getPersistenceState();
            if(state==PersistenceState.MODIFIED) {
>>> if(QueryUtils.updatedProperties(dobj)!=null) {
>>> return true; //There were some updated
properties
>>> } //no updated properties, continue and see if any other
objects have changed
            } else if (state == PersistenceState.NEW
                || state == PersistenceState.DELETED) {
                return true;
            }
        }
        return false;
    }

If one of the more experienced Cayenne developers knows the solution or
wants to offer advice on the right solution, I'd be willing to do the
work to get a patch together.

Is it as simple as combining the result of ObjectStore.hasChanges() with
looking at DataContext.getFlattenedInserts (and Deletes?) in
DataContext.hasChanges()? As in:

        return ((this.getFlattenedInserts().isEmpty() == false)
                        || (this.getFlattenedDeletes().isEmpty() ==
false)
                        || objectStore.hasChanges());

Or should ObjectStore.hasChanges() return the "right" thing based on
properties and relationships....?

Scott Finnerty



This archive was generated by hypermail 2.0.0 : Tue Jul 29 2003 - 14:42:55 EDT