-->
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.  [ 6 posts ] 
Author Message
 Post subject: Simple question about many-to-many relationships
PostPosted: Wed Feb 22, 2006 7:42 am 
Regular
Regular

Joined: Sun Nov 07, 2004 3:39 pm
Posts: 77
I've implemented a many-to-many relationship for the first time, and there are a couple of things which are unclear to me. I have two classes, Team and Competition. A Team can belong to many Competitions, a Competition can contain many Teams. So, I have successfully mapped this as a many-to-many using a bridging table, team_competition.

My first problem is now how to query to get, say, all the Teams in a given Competition. With a one-to-many (which I'm used to), I'd do:

Code:
from myproject.om.Team t where t.competition.name=?


But this, of course, no longer works with a many-to-many, as Team has a competitions Collection property, not a single Competition property.

The second problem is how to specify an order-by for the returned collection. Once again, with a one-to-many I can specify an order-by column in the many table. But what do I do when there's a bridging table in the middle?

TIA

[Hibernate 2.1.8]


Top
 Profile  
 
 Post subject:
PostPosted: Wed Feb 22, 2006 8:30 am 
Newbie

Joined: Tue Nov 15, 2005 2:16 pm
Posts: 10
you can use something like the snipet below to map a collection on your Team class

Code:
    <set name="competitions"           
         table="Competition_Team"
         order-by="order_field asc"
       >
      <key column="Team_ID" />
      <many-to-many column="Competition_ID" class="Competition"/>
    </set>


where the table's fields are:
Team: { team_id, ..... }
Competition: { competition_id, ..... }
Competition_Team: { competition_id, team_id, order_field, ... }

I hope this helps

Emilio


Top
 Profile  
 
 Post subject:
PostPosted: Wed Feb 22, 2006 9:29 am 
Regular
Regular

Joined: Sun Nov 07, 2004 3:39 pm
Posts: 77
eoca wrote:
you can use something like the snipet below to map a collection on your Team class

Code:
    <set name="competitions"           
         table="Competition_Team"
         order-by="order_field asc"
       >
      <key column="Team_ID" />
      <many-to-many column="Competition_ID" class="Competition"/>
    </set>


where the table's fields are:
Team: { team_id, ..... }
Competition: { competition_id, ..... }
Competition_Team: { competition_id, team_id, order_field, ... }

I hope this helps

Emilio


So how do I populate the Competition_Team.order_field column? At the moment the handling of the bridging table is done automatically for me by Hibernate.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Feb 22, 2006 12:52 pm 
Regular
Regular

Joined: Sun Nov 07, 2004 3:39 pm
Posts: 77
Hmm, I said I had many-to-many working, largely. In fact, I don't, and I can't see why. Here's the relevant chunk from Team.hbm.xml:

<set
name="competitions"
table="team_competition"
lazy="false"
inverse="false"
cascade="save-update"
sort="unsorted">

<key
column="team_id"></key>

<many-to-many
class="myproject.om.Competition"
column="competition_id"
outer-join="auto" />

</set>

Here's the matching chunk from Competition.hbm.xml:

<set
name="teams"
table="team_competition"
lazy="false"
inverse="false"
cascade="save-update"
sort="unsorted">

<key
column="competition_id"></key>

<many-to-many
class="myproject.om.Team"
column="team_id"
outer-join="auto" />

</set>

I could swear this is just as in the examples I've seen. And yet it doesn't work when I run the following code, which retrieves an existing newly created Competition object from the database and then attempts to create and save 4 Team objects with this Competition assigned to them.


Code:
      Competition premiership=dataService.findCompetition("English Premiership");
      String[] teams=new String[] {"Chelsea","Arsenal","Liverpool","Everton"};
      for (int i=0;i < teams.length;i++) {
         Team team=dataService.findTeam(teams[i]);
         if(team==null){
            team=new Team(teams[i]);
            HashSet compSet=new HashSet();
            compSet.add(premiership);
            team.setCompetitions(compSet);
            team=dataService.storeTeam(team);
         }
      }


When I look at the database after this process has run, the bridging table ('team_competition') only has one record in it, which is for the last of the teams created in the code above. I experimented with setting 'inverse=true' on one of the tables, but this ended up with no bridging records at all being created. I must be doing something fundamentally wrong, but I really can't see what it is. Help!


Top
 Profile  
 
 Post subject:
PostPosted: Wed Feb 22, 2006 2:00 pm 
Regular
Regular

Joined: Sun Nov 07, 2004 3:39 pm
Posts: 77
This is getting increasingly bizarre. As an experiment, I tried the following, where instead of adding the Competition to the Team, I add the team to the Competition (both classes have a Set of the other and an addXXX method which adds the respective object to the set).

Code:
    Competition premiership=dataService.findCompetition("English Premiership");
      String[] teams=new String[] {"Chelsea","Arsenal","Liverpool","Everton"};
      for (int i=0;i < teams.length;i++) {
         Team team=dataService.findTeam(teams[i]);
         if(team==null){
            team=new Team(teams[i]);
            premiership.addTeam(team);
       team=dataService.storeTeam(team);
       dataService.store(premiership);
         }
      }


What happens now is that bridging records are created for the second and fourth teams, but not the first or third. This makes no sense at all to me.

Is there any good documentation of many-to-many relations which people know about other than in the Hibernate reference (where the coverage is rather meagre)?


Top
 Profile  
 
 Post subject:
PostPosted: Wed Feb 22, 2006 3:31 pm 
Regular
Regular

Joined: Sun Nov 07, 2004 3:39 pm
Posts: 77
Well, the answer seems to be that you have to specify 'lazy="true"' for the relationships. That sorted it out.

Is this kind of stuff actually documented anywhere?


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 6 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.