cayenne-user mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Gentry, Michael \(Contractor\)" <>
Subject RE: modifying relationship list
Date Tue, 20 Jun 2006 13:04:29 GMT
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.


PS. For me, it was actually addObject:toBothSidesOfRelationshipWithKey:
... Much better.

-----Original Message-----
From: Andrus Adamchik [] 
Sent: Tuesday, June 20, 2006 2:19 AM
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.


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 <> 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
> 408 276-5638
> P.S. A good JDO? O, Gasp!

View raw message