-->
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.  [ 8 posts ] 
Author Message
 Post subject: Many-Many question
PostPosted: Fri Feb 02, 2007 6:27 pm 
Senior
Senior

Joined: Sat Aug 19, 2006 6:31 pm
Posts: 139
Hi,

I have a general question about Many-Many relationship.

Below is the generated hbm.xml file (using hibernate tools)


Code:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- Generated Sep 14, 2006 3:56:45 PM by Hibernate Tools 3.2.0.beta7 -->
<hibernate-mapping>
    <class name="example.UserGroupTbl" table="usergrouptbl">
        <comment></comment>
        <composite-id name="id" class="example.UserGroupTblId">
            <key-property name="userId" type="string">
                <column name="UserID" length="32" />
            </key-property>
            <key-property name="id" type="string">
                <column name="GroupID" length="32" />
            </key-property>
        </composite-id>
        <version name="version" column="Version" />
        <many-to-one name="user" class="example.User" update="false" insert="false" lazy="false" fetch="select">
            <column name="UserID" length="32" not-null="true">
                <comment></comment>
            </column>
        </many-to-one>
        <many-to-one name="group" class="example.Group" update="false" insert="false" lazy="false" fetch="select">
            <column name="GroupID" length="32" not-null="true">
                <comment></comment>
            </column>
        </many-to-one>
    </class>
</hibernate-mapping>


So the many to many relationship is that a user can belong to multiple groups and each group can have many users. The User and Group mapping files have one-to-many mapping to the UserGroupTbl also. In relational database, this is represented by a table with two columns; userid, and groupid both of which are foreign keys.

Now the question is. Is this the best way to represent this kind of relationship?

With this, when I need to add a user to a group, I need to do the following.

Code:
UserGroupTbl a = new UserGroupTbl();
a.setUser(user);
a.setGroup(group);

UserGroupTblId id = new UserGroupTblId();
id.setUserId(user.getId());
id.setGroupId(group.getId());

// Need to do this because the id for UserGroupTbl is not hibernate generated.
a.setId(id);


It seems like this more complex than it needs to be. We should be able to just do a setuser() and setGroup() and not worry about UserGroupTblId ourselves.

Second question is what should be done when User and Group are new i.e. they are transient (never persisted before)?. I would like to be able to just do a session.save(user) and let hibernate cascades deal with persisting the rest. So the new UserGroupTbl would automatically be persisted and so is the new Group. With the mapping file shown above it seems like this cannot be done because it requires an id for User and Group to have been generated first.

Thanks in advance.
Budyanto


Top
 Profile  
 
 Post subject:
PostPosted: Sat Feb 03, 2007 3:48 am 
Senior
Senior

Joined: Tue Aug 23, 2005 8:52 am
Posts: 181
Do you have mappings from the User and Group object(one-to-many) to the UserGroupTbl? something like
Code:
In User.hbm.xml
<set name="groups" table="usergrouptbl"  cascade="save-update">
    <key column="UserID"/>
   <one-to-many class="Group" />
</set>

and similarly for Group.hbm.xml

Since on the UserGroupTbl , you have defined insert="true" and update="true" on both the many-to-one mappings, the UserGroupTbl.setUser and UserGroupTbl.setGroup have absolutely no meaning because hibernate would not use those to insert any values. This is the equivalent of having a inverse="true" on the UserGroupTbl side.

If you have a mapping like given above for User.hbm.xml and Group.hbm.xml, you could use those to store the association (and since the cascade is present, it should automatically create newer User/Group objects and also insert into the association table).


Top
 Profile  
 
 Post subject:
PostPosted: Sat Feb 03, 2007 4:19 am 
Senior
Senior

Joined: Sat Aug 19, 2006 6:31 pm
Posts: 139
rajasaur wrote:
Do you have mappings from the User and Group object(one-to-many) to the UserGroupTbl? something like
Code:
In User.hbm.xml
<set name="groups" table="usergrouptbl"  cascade="save-update">
    <key column="UserID"/>
   <one-to-many class="Group" />
</set>

and similarly for Group.hbm.xml


Yes I do.

rajasaur wrote:
Since on the UserGroupTbl , you have defined insert="true" and update="true" on both the many-to-one mappings, the UserGroupTbl.setUser and UserGroupTbl.setGroup have absolutely no meaning because hibernate would not use those to insert any values. This is the equivalent of having a inverse="true" on the UserGroupTbl side.


Actually I didn't have insert="true" on the many-to-one mapping. You are asying I should set it to true? I'll give that a try.

rajasaur wrote:
If you have a mapping like given above for User.hbm.xml and Group.hbm.xml, you could use those to store the association (and since the cascade is present, it should automatically create newer User/Group objects and also insert into the association table).

Now what about the composite id in the UserGroupTbl mapping file? I would get an exception saying that I need to supply the composite id because it's not hibernate generated wouldn't I?


Top
 Profile  
 
 Post subject:
PostPosted: Sat Feb 03, 2007 5:26 am 
Senior
Senior

Joined: Tue Aug 23, 2005 8:52 am
Posts: 181
himawan wrote:

rajasaur wrote:
Since on the UserGroupTbl , you have defined insert="true" and update="true" on both the many-to-one mappings, the UserGroupTbl.setUser and UserGroupTbl.setGroup have absolutely no meaning because hibernate would not use those to insert any values. This is the equivalent of having a inverse="true" on the UserGroupTbl side.


Actually I didn't have insert="true" on the many-to-one mapping. You are asying I should set it to true? I'll give that a try.

No I meant its the equivalent of having inverse="true". You cannot have an inverse attribute on the many-to-one mapping.

himawan wrote:
Now what about the composite id in the UserGroupTbl mapping file? I would get an exception saying that I need to supply the composite id because it's not hibernate generated wouldn't I?

Do you have any other columns in the association table other than the foreign keys of the participating entities? If you dont , you could just map it as 2 Sets(one each from User and Group). Since its a Set, both the keys automatically form the composite-key and there is nothing to worry from a user's perspective. But if you have any extra columns, thats a different case. From your original posting, it looked like hibernate-tools created a table with composite-id, Do you have any extra columns (in addition to the foreign keys) in that table?


Top
 Profile  
 
 Post subject:
PostPosted: Sat Feb 03, 2007 3:42 pm 
Senior
Senior

Joined: Sat Aug 19, 2006 6:31 pm
Posts: 139
Quote:
Do you have any other columns in the association table other than the foreign keys of the participating entities? If you dont , you could just map it as 2 Sets(one each from User and Group). Since its a Set, both the keys automatically form the composite-key and there is nothing to worry from a user's perspective. But if you have any extra columns, thats a different case. From your original posting, it looked like hibernate-tools created a table with composite-id, Do you have any extra columns (in addition to the foreign keys) in that table?


No, I don't have any other columns; just the two foreign keys. Yes the UserGroupTbl mapping file was generated by hibernate tools. When I tried removing composite-id from the mapping file it gave me this error:

Code:
The content of element type "class" must match
"(meta*,subselect?,cache?,synchronize*,comment?,tuplizer*,
(id|composite-id),discriminator?,natural-id?,(version|
timestamp)?,(property|many-to-one|one-to-one|component|
dynamic-component|properties|any|map|set|list|bag|idbag|
array|primitive-array)*,((join*,subclass*)|joined-subclass*|
union-subclass*),loader?,sql-insert?,sql-update?,sql-
delete?,filter*,resultset*,(query|sql-query)*)".


So at least id or composite-id needs to be present in a mapping file. Or do I even need the mapping file at all for UserGroupTbl then?

Thanks
Budyanto


Top
 Profile  
 
 Post subject:
PostPosted: Sat Feb 03, 2007 9:07 pm 
Senior
Senior

Joined: Sat Aug 19, 2006 6:31 pm
Posts: 139
Allright I think I got it now:

Here's a portion of User.hbm.xml:
Code:
<set name="groups" table="usergrouptbl" cascade="save-update">
       <key>
            <column name="userid" not-null="true" />
        </key>
        <many-to-many entity-name="example.Group">
            <column name="groupid" not-null="true" />
        </many-to-many>
</set>


Here's from Group.hbm.xml:
Code:
<set name="users" table="usergrouptbl" cascade="save-update" inverse="true">
        <key>
            <column name="groupid" not-null="true" />
        </key>
        <many-to-many entity-name="example.User">
            <column name="userid" not-null="true" />
        </many-to-many>
</set>


Now whenever I need to assign a new User to a new Group. All I need to do is the following:
Code:
User u = new User();
Group g = new Group();
u.getGroups().add(g);
g.getUsers().add(u);
session.save(u);


And when I delete a user, the right rows are deleted from the UserGroupTbl. And I don't need to have UserGroupTbl.hbm.xml.


Top
 Profile  
 
 Post subject:
PostPosted: Sun Feb 04, 2007 4:01 am 
Newbie

Joined: Sun Feb 04, 2007 3:59 am
Posts: 1
What is Hibernate?

_________________
Asia
teens
want
best
pink
tits


Top
 Profile  
 
 Post subject:
PostPosted: Mon Feb 05, 2007 12:23 am 
Regular
Regular

Joined: Tue Jan 03, 2006 9:20 am
Posts: 74
Andreo27 wrote:
What is Hibernate?


sleeping through the winter, which is what intelligent creatures do.


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