-->
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.  [ 15 posts ] 
Author Message
 Post subject: Bidirecional N-N shared table
PostPosted: Wed Dec 03, 2003 8:10 am 
Regular
Regular

Joined: Wed Sep 10, 2003 7:09 am
Posts: 63
Hi,

I have a bidirecional many-to-many relation between classes A and B. A uses an association table AtoB and B uses an association table BtoA. I am using lists in both sides.

My ideia was to use AtoB and BtoA on the same table, creating a single four filed association table with the following fields:
1 - keyA
2 - keyB
3 - index AtoB
4 - index BtoA

The A side mapping would use fields 1, 2 and 3, and B side mapping would use fields 1, 2 and 4.

My question is: is it safe to do this? Or does it have to be two tables?

Thanks in advance,
Joao Rangel


Top
 Profile  
 
 Post subject:
PostPosted: Wed Dec 03, 2003 9:11 am 
Hibernate Team
Hibernate Team

Joined: Sun Sep 14, 2003 3:54 am
Posts: 7256
Location: Paris, France
Why do you use separate tables and colums ? This is not the appropriate mapping. Otherwise it's 2 different many to many links (not bidirectional)

_________________
Emmanuel


Top
 Profile  
 
 Post subject: Many-to-many
PostPosted: Wed Dec 03, 2003 10:20 am 
Regular
Regular

Joined: Wed Sep 10, 2003 7:09 am
Posts: 63
Well, imagine the following situation: I have class user and class group. A user belongs to many groups, and a group may have many users. This is a many-to-many relation.

When I add a user to a group, I want to add the group to the user too. If I had one association table, instead of two, I may optimize the number of accesses and operations.

Is that right?


Top
 Profile  
 
 Post subject:
PostPosted: Wed Dec 03, 2003 11:09 am 
Hibernate Team
Hibernate Team

Joined: Sun Sep 14, 2003 3:54 am
Posts: 7256
Location: Paris, France
As I told you you do not need 2 tables or event 1 table and 4 columns.
1 table and 2 columns is enough. Actually the bidirectional many-to-many is done for that.

Have a look at the example in the reference guide (self many to many)

Code:
<class name="eg.Node">
    <id name="id" column="id"/>
    ....
    <bag name="accessibleTo" table="node_access" lazy="true">
        <key column="to_node_id"/>
        <many-to-many class="eg.Node" column="from_node_id"/>
    </bag>
     <!-- inverse end -->
    <bag name="accessibleFrom" table="node_access" inverse="true" lazy="true">
        <key column="from_node_id"/>
        <many-to-many class="eg.Node" column="to_node_id"/>
    </bag>
</class>


the key column of the first association is the manytomany column of the second one, and same for inverse.

_________________
Emmanuel


Top
 Profile  
 
 Post subject: Inverse
PostPosted: Wed Dec 03, 2003 11:33 am 
Regular
Regular

Joined: Wed Sep 10, 2003 7:09 am
Posts: 63
I read the documentation many times, but only now i think i understand the meaning of inverse. In the documentation it says:

"Please note that Hibernate doesn't support bidirectional associations with list, map or array values (indexed collections) for the "many" end of a one-to-many association!"

But I am using lists. Is it possible to keep using lists, if I use diferent columns for the two indexes?


Top
 Profile  
 
 Post subject:
PostPosted: Wed Dec 03, 2003 11:41 am 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 12:50 pm
Posts: 5130
Location: Melbourne, Australia
The documentation is wrong. It should say "one-to-many associations", not "associations".


Top
 Profile  
 
 Post subject:
PostPosted: Wed Dec 03, 2003 11:43 am 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 12:50 pm
Posts: 5130
Location: Melbourne, Australia
actually the doco is correct, just badly worded. it says "one-to-many" at the end of the sentence.


Top
 Profile  
 
 Post subject: One more question
PostPosted: Wed Dec 03, 2003 11:49 am 
Regular
Regular

Joined: Wed Sep 10, 2003 7:09 am
Posts: 63
I am getting a error because Hibernate doesn't find the "accessibleFrom" property in the source class. Shouldn't this property be mapped in the destination class?


Top
 Profile  
 
 Post subject:
PostPosted: Wed Dec 03, 2003 11:50 am 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 12:50 pm
Posts: 5130
Location: Melbourne, Australia
If you have two classes, of course!

Emmanuel's example was for a recursive association.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Dec 03, 2003 11:53 am 
Hibernate Team
Hibernate Team

Joined: Sun Sep 14, 2003 3:54 am
Posts: 7256
Location: Paris, France
Sorry I was too lazy to adapt the sample to your case ;-)

_________________
Emmanuel


Top
 Profile  
 
 Post subject: Inverse
PostPosted: Wed Dec 03, 2003 12:05 pm 
Regular
Regular

Joined: Wed Sep 10, 2003 7:09 am
Posts: 63
Yes, I have two classes and I am not making direct copy paste.

Here is may maps:

<class User>
...
<list name="objects" table="UserObject">
<key column="keyUser"/>
<index column="indexUser"/>
<many-to-many column="keyObject" class="Object"/>
</list>

<list name="users" table="UserObject" inverse="true">
<key column="keyObject"/>
<index column="indexObject"/>
<many-to-many column="keyUser" class="User"/>
</list>
</class>

<class Object>
</class>


In java classes, 'objects' belongs do the User class, and 'users' belongs to Object class. And this is the error:


SEVERE: Could not compile the mapping document
net.sf.hibernate.MappingException: Problem trying to set property type by reflection at net.sf.hibernate.mapping.Value.setTypeByReflection(Value.java:102)
at net.sf.hibernate.cfg.Binder.createProperty(Binder.java:956)
at net.sf.hibernate.cfg.Binder.propertiesFromXML(Binder.java:949)
at net.sf.hibernate.cfg.Binder.bindRootClass(Binder.java:312)
at net.sf.hibernate.cfg.Binder.bindRoot(Binder.java:1146)
at net.sf.hibernate.cfg.Configuration.add(Configuration.java:243)
at net.sf.hibernate.cfg.Configuration.addFile(Configuration.java:165)
at net.sf.hibernate.tool.hbm2ddl.SchemaExport.main(SchemaExport.java:282)
Caused by: net.sf.hibernate.PropertyNotFoundException: Could not find a getter for users in class User
at net.sf.hibernate.property.BasicPropertyAccessor.getGetter(BasicPropertyAccessor.java:186)
at net.sf.hibernate.util.ReflectHelper.reflectedPropertyType(ReflectHelper.java:57)
at net.sf.hibernate.mapping.Value.setTypeByReflection(Value.java:91)


I supposed that users should be in the destination class (Object). Why is Hibernate searching for it in the User side?


Top
 Profile  
 
 Post subject:
PostPosted: Wed Dec 03, 2003 12:09 pm 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 12:50 pm
Posts: 5130
Location: Melbourne, Australia
Cos you have it mapped on the user side, according to what you just showed!

change to:

<class User>
...
<list name="objects" table="UserObject">
<key column="keyUser"/>
<index column="indexUser"/>
<many-to-many column="keyObject" class="Object"/>
</list>
</class>


<class Object>
<list name="users" table="UserObject" inverse="true">
<key column="keyObject"/>
<index column="indexObject"/>
<many-to-many column="keyUser" class="User"/>
</list>
</class>


Top
 Profile  
 
 Post subject: Solved
PostPosted: Wed Dec 03, 2003 12:21 pm 
Regular
Regular

Joined: Wed Sep 10, 2003 7:09 am
Posts: 63
It's working... Thanks again for the Hibernate Team help.


Top
 Profile  
 
 Post subject: One more question...
PostPosted: Wed Dec 03, 2003 2:21 pm 
Regular
Regular

Joined: Wed Sep 10, 2003 7:09 am
Posts: 63
I would like to make you one more question about this subject:
Is there any way to add a property to an association table?


Top
 Profile  
 
 Post subject:
PostPosted: Wed Dec 03, 2003 3:00 pm 
Hibernate Team
Hibernate Team

Joined: Sun Sep 14, 2003 3:54 am
Posts: 7256
Location: Paris, France
Yes
section 7.2

A special case of a composite element is a composite element with a nested <many-to-one> element. A mapping like this allows you to map extra columns of a many-to-many association table to the composite element class. The following is a many-to-many association from Order to Item where purchaseDate, price and quantity are properties of the association:

Code:
<class name="eg.Order" .... >
    ....
    <set name="purchasedItems" table="purchase_items" lazy="true">
        <key column="order_id">
        <composite-element class="eg.Purchase">
            <property name="purchaseDate"/>
            <property name="price"/>
            <property name="quantity"/>
            <many-to-one name="item" class="eg.Item"/> <!-- class attribute is optional -->
        </composite-element>
    </set>
</class>

_________________
Emmanuel


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