Re: modifying relationship list

From: Andrus Adamchik (andru..bjectstyle.org)
Date: Tue Jun 20 2006 - 09:23:16 EDT

  • Next message: Craig L Russell: "Re: modifying relationship list"

    > Monstrous?

    In Objective C you'd read a method name with a list of arguments
    almost as a sentence in a human language. So it was verbose, but
    readable. I was referring to its Java reincarnation - when
    concatenated in one word it looks horrible and almost impossible to
    type correctly for such impaired keyboard users like myself :-)

    Of course my purpose wasn't EOF bashing, but rather pointing to the
    importance of the automated reverse relationship management :-)

    Andrus

    On Jun 20, 2006, at 5:04 PM, Gentry, Michael ((Contractor)) wrote:

    > Monstrous? That was my favorite method name! It stated precisely
    > what
    > it was doing, too. :-) We hardly ever removed anything, so never got
    > to use removeObjectFromBothSidesOfRelationshipWithKey all that much.
    > Sigh.
    >
    > /dev/mrg
    >
    > PS. For me, it was actually
    > addObject:toBothSidesOfRelationshipWithKey:
    > ... Much better.
    >
    >
    >
    > -----Original Message-----
    > From: Andrus Adamchik [mailto:andru..bjectstyle.org]
    > Sent: Tuesday, June 20, 2006 2:19 AM
    > To: cayenne-use..ncubator.apache.org
    > Subject: Re: modifying relationship list
    >
    >
    >>
    >> "Someone" should write a paper.
    >
    > Yep :-)
    >
    > I recall back in my WebObjects/EOF days, instead of using property
    > setters I always used a generic method with monstrous name of the
    > Objective C heritage - "addObjectToBothSidesOfRelationshipWithKey"
    > and its counterpart "removeObjectFromBothSidesOfRelationshipWithKey"
    > exactly because it helped with graph consistency.
    >
    > So bidirectional relationship management was one of the first
    > features in the early Cayenne to address that.
    >
    > Andrus
    >
    >
    > On Jun 19, 2006, at 8:51 PM, Craig L Russell wrote:
    >
    >> Hi,
    >>
    >> This relationship change issue is a very old one in object modeling
    >> and made even more interesting when mapping to a relational
    >> database, where typically there is only one database column value
    >> that represents both sides of the relationship.
    >>
    >> Among the standards for persistence (J2EE CMP, JDO 1, JDO 2, and
    >> EJB3) the requirements are all over the map, with little to guide
    >> you.
    >>
    >> CMP defines the behavior as I understand Cayenne currently
    >> implements it. That is, the relationship on the other side is
    >> silently changed to be consistent.
    >>
    >> JDO 1 is silent on the issue.
    >>
    >> JDO 2 defines the behavior as "undefined until commit or flush", at
    >> which point the relationships on both sides are silently changed to
    >> be consistent.
    >>
    >> EJB3 is silent, and allows relationships to be inconsistent after
    >> commit.
    >>
    >> I believe it is tricky to code defensively if you want to manage
    >> relationships in memory. The issue is the possibility of updating
    >> the relationship from either side. The apparently straightforward
    >> technique is to implement the Room.setSite method to call
    >> oldRoom.remove(this) and newRoom.add(this). And the Site.remove
    >> method to call theRoom.setSite(null) and Site.add method to call
    >> theRoom.setSite(this). But this causes recursion, unless you use
    >> special add, remove, and set methods, that need to be protected
    >> from public callers. That is, define package protected methods
    >> uncoordinatedAdd, uncoordinatedRemove, and uncoordinatedSet that
    >> don't manage the other side, but are called from within the public-
    >> visible implementations of add, remove, and set. But clearly this
    >> is a lot of work for developers, so it's nice that the persistence
    >> implementation does some of the hard work for you.
    >>
    >> "Someone" should write a paper.
    >>
    >> Craig
    >>
    >> On Jun 19, 2006, at 1:12 AM, Tomi NA wrote:
    >>
    >>> On 6/19/06, Marcin Skladaniec <marci..sh.com.au> wrote:
    >>>> Hello
    >>>> Just run into interesting cayenne feature.
    >>>>
    >>>> This code:
    >>>>
    >>>> rooms = site.getRooms();
    >>>> rooms.remove(aRoom);
    >>>>
    >>>> would alter the relationship
    >>>>
    >>>> so aRoom.getSite() is now null
    >>>>
    >>>> I'm wondering if this is a desired effect ?
    >>>> This behavior might cause bugs. When someone actually puts code to
    >>>> know the fact of relationship being changed (ie. put code into Room
    >>>> setSite() and Site add/removeFromRooms()/setRooms() methods ) he
    >>>> might be disappointed, as those methods would not run, but the
    >>>> relationship will change...
    >>>
    >>> I'm wrestling with this issue myself: I've extended the basic
    >>> templates so that events are fired on setter calls, but this
    >>> practice
    >>> has the exact shortcomings you pointed out.
    >>> Is there a very good reason why cayenne objects don't fire events
    >>> on a
    >>> lower level (circumventing this problem) out of the box?
    >>> Alternatively, if I expand my object code generation templates
    >>> further
    >>> so that objectA.removeFrom(objectB) fires a property change event
    >>> for
    >>> it's objectA.getBArray() as well as objectB.getToA() - will this
    >>> completely solve the problem?
    >>>
    >>> t.n.a.
    >>
    >> Craig Russell
    >> Architect, Sun Java Enterprise System http://java.sun.com/products/
    >> jdo
    >> 408 276-5638 mailto:Craig.Russel..un.com
    >> P.S. A good JDO? O, Gasp!



    This archive was generated by hypermail 2.0.0 : Tue Jun 20 2006 - 09:23:41 EDT