You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@cayenne.apache.org by "Alexander Lamb (dev)" <al...@mac.com> on 2007/06/19 18:08:07 UTC

Duplicates in to-many relationships

Hello list,

It looks like "myFirstObject.addToMyRelation(mySecondObject)" does  
not check if mySecondObject is already in the relationship. Is that  
correct?

If so, here is my problem.

I know that I can simply do:

mySecondObject.setTheObject(myFirstObject)

and then once saved, somehow the reverse relationship will be updated.

The problem is that I need the reverse relationship before I save.  
Therefore I do:

mySecondObject.setTheObject(myFirstObject)

and

myFirstObject.addToMyRelation(mySecondObject)

In order to have my object graph correct before save.

Unfortunately, doing this it seems like mySecondObject gets inserted  
twice in the List. If I restart the app, everything is fine again.

Thanks for any hint!

Alex

RE: Duplicates in to-many relationships

Posted by Kevin Menard <km...@servprise.com>.
 

> -----Original Message-----
> From: Alexander Lamb (dev) [mailto:alamb@mac.com] 
> Sent: Wednesday, June 20, 2007 3:24 AM
> To: user@cayenne.apache.org
> Subject: Re: Duplicates in to-many relationships
> 
> Well, although it works, I still have a small problem.
> 
> When you do a "setAnObject" even if it does "magically" 
> handle the "addTo", it does so without calling the public 
> "addToMyList" function.
> 
> This means I can't add some logic to the addTo function (I 
> need to perform some calculation each time a new object is 
> added to the list.
> 
> So either I find some sort of "objectWasAddedToRelationship" 
> delegate message, or I will need to trigger the calculation 
> also from the "setAnObject" side.


I think you'll find that overriding addToManyTarget() will take care of
most (all?) cases for you, rather than override the public methods on
each of your individual CDOs.  For example, I have:

public class EnhancedCayenneDataObject extends CayenneDataObject
{
    @Override
    public void addToManyTarget(final String relName, final DataObject
value, final boolean setReverse)
    {
        final List list = (List) readProperty(relName);
        
        if (false == list.contains(value))
        {
            super.addToManyTarget(relName, value, setReverse);
        }
    }
}


> To answer directly your question, I do need sometimes a 
> sorted list but I usually don't touch the to-many relation. I 
> simply create a new function which sorts the to-many list. In 
> order to boost performance, I do keep an ArrayList variable 
> which is calculated once and only reset when the to-many list 
> changes. Another reason to need to be able to access the 
> addToMyList when I can reset my calculated sorted list.

I wasn't talking about sorted, but rather ordered.  List provides
ordered semantics, while Set does not.  Set, however, does not allow
duplicates, while List does.  Both ordered and unique are desired
properties.  The DB will not allow duplicates and will provide an
ordering, so it'd be helpful if the data model matched that, IMO.

-- 
Kevin

Re: Duplicates in to-many relationships

Posted by "Alexander Lamb (dev)" <al...@mac.com>.
Well, although it works, I still have a small problem.

When you do a "setAnObject" even if it does "magically" handle the  
"addTo", it does so without calling the public "addToMyList" function.

This means I can't add some logic to the addTo function (I need to  
perform some calculation each time a new object is added to the list.

So either I find some sort of "objectWasAddedToRelationship" delegate  
message, or I will need to trigger the calculation also from the  
"setAnObject" side.

To answer directly your question, I do need sometimes a sorted list  
but I usually don't touch the to-many relation. I simply create a new  
function which sorts the to-many list. In order to boost performance,  
I do keep an ArrayList variable which is calculated once and only  
reset when the to-many list changes. Another reason to need to be  
able to access the addToMyList when I can reset my calculated sorted  
list.

Alex

Le 19 juin 07 à 23:12, Kevin Menard a écrit :

> While this is true, I always thought a ToManyList really should be an
> ordered set.  I must admit, I was a bit perplexed the first time I  
> ended
> up with duplicates in one of my lists, but found the DB inserts were
> correct.  I actually had one Web app where it wasn't clear how
> duplicates were getting in at all, so I wrote an
> EnhancedCayenneDataObject that specifically disallowed duplicates  
> being
> added.  A bit of a performance hit, for sure, but the underlying data
> model matched the DB much more accurately and I only paid the price  
> when
> calling on of the add-to-list methods.
>
> -- 
> Kevin
>
>> -----Original Message-----
>> From: Mike Kienenberger [mailto:mkienenb@gmail.com]
>> Sent: Tuesday, June 19, 2007 12:15 PM
>> To: user@cayenne.apache.org
>> Subject: Re: Duplicates in to-many relationships
>>
>> Unlike Hibernate, the object graph is maintained even before you  
>> save.
>>
>> If you use "mySecondObject.setTheObject(myFirstObject)", then
>> the equivalent for
>> "myFirstObject.addToMyRelation(mySecondObject)" is already
>> done for you.
>>
>> This is why you're seeing two copies -- you're effectively
>> calling the addToMyRelationship twice.


RE: Duplicates in to-many relationships

Posted by Kevin Menard <km...@servprise.com>.
While this is true, I always thought a ToManyList really should be an
ordered set.  I must admit, I was a bit perplexed the first time I ended
up with duplicates in one of my lists, but found the DB inserts were
correct.  I actually had one Web app where it wasn't clear how
duplicates were getting in at all, so I wrote an
EnhancedCayenneDataObject that specifically disallowed duplicates being
added.  A bit of a performance hit, for sure, but the underlying data
model matched the DB much more accurately and I only paid the price when
calling on of the add-to-list methods.

-- 
Kevin 

> -----Original Message-----
> From: Mike Kienenberger [mailto:mkienenb@gmail.com] 
> Sent: Tuesday, June 19, 2007 12:15 PM
> To: user@cayenne.apache.org
> Subject: Re: Duplicates in to-many relationships
> 
> Unlike Hibernate, the object graph is maintained even before you save.
> 
> If you use "mySecondObject.setTheObject(myFirstObject)", then 
> the equivalent for 
> "myFirstObject.addToMyRelation(mySecondObject)" is already 
> done for you.
> 
> This is why you're seeing two copies -- you're effectively 
> calling the addToMyRelationship twice.

Re: Duplicates in to-many relationships

Posted by "Alexander Lamb (dev)" <al...@mac.com>.
Thanks a lot. It is again my WO habit where we did the  
"addToBothSidesOfRelationshipWithKey" !

Works fine now!

Alex

Le 19 juin 07 à 18:17, Mike Kienenberger a écrit :

> And note that if you call
> "myFirstObject.addToMyRelation(mySecondObject)", then
> "mySecondObject.setTheObject(myFirstObject)" is also called.   It
> doesn't matter which side of the relationship you call.   Furthermore,
> if mySecondObject.getTheObject() = myZeroObject beforehand, this
> object will also be removed from the relationship list automatically.
> Ie, everything "just works" out of the box with no extra effort on
> your part.
>
> On 6/19/07, Mike Kienenberger <mk...@gmail.com> wrote:
>> Unlike Hibernate, the object graph is maintained even before you  
>> save.
>>
>> If you use "mySecondObject.setTheObject(myFirstObject)", then the
>> equivalent for "myFirstObject.addToMyRelation(mySecondObject)" is
>> already done for you.
>>
>> This is why you're seeing two copies -- you're effectively calling  
>> the
>> addToMyRelationship twice.
>>
>>
>>
>> On 6/19/07, Alexander Lamb (dev) <al...@mac.com> wrote:
>> > Hello list,
>> >
>> > It looks like "myFirstObject.addToMyRelation(mySecondObject)" does
>> > not check if mySecondObject is already in the relationship. Is that
>> > correct?
>> >
>> > If so, here is my problem.
>> >
>> > I know that I can simply do:
>> >
>> > mySecondObject.setTheObject(myFirstObject)
>> >
>> > and then once saved, somehow the reverse relationship will be  
>> updated.
>> >
>> > The problem is that I need the reverse relationship before I save.
>> > Therefore I do:
>> >
>> > mySecondObject.setTheObject(myFirstObject)
>> >
>> > and
>> >
>> > myFirstObject.addToMyRelation(mySecondObject)
>> >
>> > In order to have my object graph correct before save.
>> >
>> > Unfortunately, doing this it seems like mySecondObject gets  
>> inserted
>> > twice in the List. If I restart the app, everything is fine again.
>> >
>> > Thanks for any hint!
>> >
>> > Alex
>> >
>>


Re: Duplicates in to-many relationships

Posted by Mike Kienenberger <mk...@gmail.com>.
And note that if you call
"myFirstObject.addToMyRelation(mySecondObject)", then
"mySecondObject.setTheObject(myFirstObject)" is also called.   It
doesn't matter which side of the relationship you call.   Furthermore,
if mySecondObject.getTheObject() = myZeroObject beforehand, this
object will also be removed from the relationship list automatically.
 Ie, everything "just works" out of the box with no extra effort on
your part.

On 6/19/07, Mike Kienenberger <mk...@gmail.com> wrote:
> Unlike Hibernate, the object graph is maintained even before you save.
>
> If you use "mySecondObject.setTheObject(myFirstObject)", then the
> equivalent for "myFirstObject.addToMyRelation(mySecondObject)" is
> already done for you.
>
> This is why you're seeing two copies -- you're effectively calling the
> addToMyRelationship twice.
>
>
>
> On 6/19/07, Alexander Lamb (dev) <al...@mac.com> wrote:
> > Hello list,
> >
> > It looks like "myFirstObject.addToMyRelation(mySecondObject)" does
> > not check if mySecondObject is already in the relationship. Is that
> > correct?
> >
> > If so, here is my problem.
> >
> > I know that I can simply do:
> >
> > mySecondObject.setTheObject(myFirstObject)
> >
> > and then once saved, somehow the reverse relationship will be updated.
> >
> > The problem is that I need the reverse relationship before I save.
> > Therefore I do:
> >
> > mySecondObject.setTheObject(myFirstObject)
> >
> > and
> >
> > myFirstObject.addToMyRelation(mySecondObject)
> >
> > In order to have my object graph correct before save.
> >
> > Unfortunately, doing this it seems like mySecondObject gets inserted
> > twice in the List. If I restart the app, everything is fine again.
> >
> > Thanks for any hint!
> >
> > Alex
> >
>

Re: Duplicates in to-many relationships

Posted by Mike Kienenberger <mk...@gmail.com>.
Unlike Hibernate, the object graph is maintained even before you save.

If you use "mySecondObject.setTheObject(myFirstObject)", then the
equivalent for "myFirstObject.addToMyRelation(mySecondObject)" is
already done for you.

This is why you're seeing two copies -- you're effectively calling the
addToMyRelationship twice.



On 6/19/07, Alexander Lamb (dev) <al...@mac.com> wrote:
> Hello list,
>
> It looks like "myFirstObject.addToMyRelation(mySecondObject)" does
> not check if mySecondObject is already in the relationship. Is that
> correct?
>
> If so, here is my problem.
>
> I know that I can simply do:
>
> mySecondObject.setTheObject(myFirstObject)
>
> and then once saved, somehow the reverse relationship will be updated.
>
> The problem is that I need the reverse relationship before I save.
> Therefore I do:
>
> mySecondObject.setTheObject(myFirstObject)
>
> and
>
> myFirstObject.addToMyRelation(mySecondObject)
>
> In order to have my object graph correct before save.
>
> Unfortunately, doing this it seems like mySecondObject gets inserted
> twice in the List. If I restart the app, everything is fine again.
>
> Thanks for any hint!
>
> Alex
>