-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 4 posts ] 
Author Message
 Post subject: Many-to-many collection problem
PostPosted: Mon Oct 22, 2007 10:28 am 
Newbie

Joined: Sat Jan 14, 2006 8:03 pm
Posts: 18
Hibernate version: 3.2.5.ga

I have posted on this before. I got no replies, so I parked the issue and moved on but now I have to deal with it. Because of my limited Hibernate knowledge, I am not even really sure of what things to try anymore. Can someone shed some light on this problem for me?

I have two Objects, ObjectA and ObjectB. They have a ManyToMany relationship between them with attributes, meaning they have a JOIN table with IdObjectA and IdObjectB as foreign keys and some attributes. As recommended by the Hibernate docs, I create a class, AAndBJoin, to represent the JOIN. Here's what it all looks like:

Code:
public class ObjectA
{
  private Set<AAndBJoin> aAndBJoins;

  @OneToMany(mappedBy="ObjectA", fetch = FetchType.EAGER, cascade = { CascadeType.ALL })
  public Set<AAndBJoin> getAAndBJoins ()

public class ObjectB
{
  private Set<AAndBJoin> aAndBJoins;

  @OneToMany(mappedBy="ObjectB")
  public Set<AAndBJoin> getAAndBJoins ()

public class AAndBJoin
{
  private ObjectA objectA;
  private ObjectB objectB;

  @ManyToOne
  @JoinColumn(name="idObjectA")
  public ObjectA getObjectA()

  @ManyToOne
  @JoinColumn(name="idObjectB")
  public ObjectB getObjectB()


The problem is that when I save an ObjectA, with its associated Set of AAndBJoin Objects, ONLY inserts are done in the AAndBJoin table in the database, any existing information is NOT being updated or deleted. So if I start off with 2 AAndBJoin Objects and add 1, instead of having 3 I now have 5 because 3 inserts are performed, one for each AAndBJoin Object sent to the FormController from the .jsp, but the original 2 are left untouched.

Do I have to play with the AAndBJoin Object, like add Cascade information or something else? In the example there was none, and I have tried putting Cascade.ALL for the two getters, no dice. Or perhaps I have to do something manually, like call session.flush() or something, to get Hibernate to delete the info in the AAndBJoin table first before inserting, as I see it does (using log4j to debug the generated SQL) when using a 'normal' ManyToMany relationship, ie. a JOIN table without attributes and as such no need to create a class to represent the JOIN table, as is my case.

I have also looked at the Category / Item / CategorizedItem code in the CaveatEmptor app but it doesn't do the trick either.

I would really appreciate some help on this one!

Bob


Top
 Profile  
 
 Post subject:
PostPosted: Mon Oct 22, 2007 11:49 am 
Newbie

Joined: Tue Oct 02, 2007 11:57 am
Posts: 5
Not sure, but since your object represent the many-to-many association, the intersection table will only have insert or deletes on it. It's not really an "updatable" entity.

So you may have to set the cascade to "all,delete-orphan" to tell hibernate to check for orphans and delete them.

I would try this in your situation. BUT, it is quite strange that hibernate generates 3 inserts if you only add 1 item... haven't you overloaded the hashCode / equals method in an inconsistent way ?

Not much, but hope this helps.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Oct 24, 2007 9:34 am 
Newbie

Joined: Sat Jan 14, 2006 8:03 pm
Posts: 18
Thanks for the response. Someone over at the Appfuse list pointed something out to me that I had completely overlooked - in order for Hibernate to know to update I have to pass it the id of each AAndBJoin Object associated with ObjectA. Otherwise it assumes they are new AAndBJoin Objects and will do inserts.

So I am no longer getting duplicates. However, if I change any info it is not getting updated. And if I delete, it doesn't delete. Just before calling save in my Spring Form Controller I take a look at the data and it's all correct. But no change is made.

I turned on Hibernate SQL DEBUG and at least for the updates I see a line of SQL that *should* be updating correctly:

Code:
update AAndBJoin set idObjectA=?, idObjectB=?, text=? where idAAndBJoin=?


But I don't know what values are being passed in. They can't be the ones from my form because as I said, those values are correct. Is there any way to see what the values passed to the PreparedStatement are?

I think I have already tried putting 'delete-orphan', on the getters (getObjectA(), getObjectB()) for the AAndBJoin object and it was deleting any and all data. Or do I need to put in in the getAAndBJoin() method of ObjectA?

I'll keep playing around until I hopefully figure it out. Thanks again for your help!

Bob


Top
 Profile  
 
 Post subject:
PostPosted: Sat Oct 27, 2007 7:39 am 
Beginner
Beginner

Joined: Mon Aug 27, 2007 8:10 am
Posts: 37
syg6 wrote:

I think I have already tried putting 'delete-orphan', on the getters (getObjectA(), getObjectB()) for the AAndBJoin object and it was deleting any and all data. Or do I need to put in in the getAAndBJoin() method of ObjectA?

I'll keep playing around until I hopefully figure it out. Thanks again for your help!

Bob


We have similar problem which we solved with @SQLDelete and @SQLDeleteAll (the latter one indeed has a bug at annotation level and does not work as it should, but anyway after patching it at run time we got it working).

Custom SQLs do not seem right but we do not know other solution. If you find, please let us know as well.


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 4 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.