-->
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.  [ 7 posts ] 
Author Message
 Post subject: Multiple entities with collections of the same entity type
PostPosted: Thu Mar 24, 2005 7:50 pm 
Beginner
Beginner

Joined: Sun Feb 20, 2005 12:14 am
Posts: 49
Hibernate Version: 3.0

We have three persistent classes, P1, P2, and Description. P1 and P2 both have a collection of Description entities. This setup works fine if we define our mappings like this:

Code:
<hibernate-mapping>
    <class name="com.am.t.beans.P1" table="p1">
        <id name="id" unsaved-value="0">
                <generator class="native"/>
        </id>
       
        <property name="name" type="string"/>
        <map name="descriptions"
            lazy="true"
            cascade="all">
            <key column="p1Id"/>
            <map-key formula="type" type="string"/>
            <one-to-many class="com.am.t.beans.Description"/>
        </map>
   </class>
</hibernate-mapping>


Code:
<hibernate-mapping>
    <class name="com.am.t.beans.P2" table="p2">
        <id name="id" unsaved-value="0">
                <generator class="native"/>
        </id>
       
        <property name="name" type="string"/>
        <map name="descriptions"
            lazy="true"
            cascade="all">
            <key column="p2Id"/>
            <map-key formula="type" type="string"/>
            <one-to-many class="com.am.t.beans.Description"/>
        </map>
   </class>
</hibernate-mapping>


Note that in P1's description collection, the key column is P1id, and in P2's collection the key column is P2id. The 'description' table hibernate creates looks like this:

Code:
+-----------+--------------+------+-----+---------+----------------+
| Field     | Type         | Null | Key | Default | Extra          |
+-----------+--------------+------+-----+---------+----------------+
| id        | bigint(20)   |      | PRI | NULL    | auto_increment |
| type      | varchar(255) | YES  |     | NULL    |                |
| text      | varchar(255) | YES  |     | NULL    |                |
| p1Id      | bigint(20)   | YES  | MUL | NULL    |                |
| p2Id      | bigint(20)   | YES  | MUL | NULL    |                |
+-----------+--------------+------+-----+---------+----------------+


This setup works properly with Hibernate.

But in some cases we may have P3, P4, P5, and P6 similar to P1 and P2. In this situation, if we used the approach above, the Description table would have p1id, p2id, p3id, p4id, p5id, and p6id. From a database perspective, we would rather define the Description table like this:

Code:
+-----------+--------------+------+-----+---------+----------------+
| Field     | Type         | Null | Key | Default | Extra          |
+-----------+--------------+------+-----+---------+----------------+
| id        | bigint(20)   |      | PRI | NULL    | auto_increment |
| type      | varchar(255) | YES  |     | NULL    |                |
| text      | varchar(255) | YES  |     | NULL    |                |
| pid       | bigint(20)   | YES  | MUL | NULL    |                |
| ptype     | varchar      | YES  | MUL | NULL    |                |
+-----------+--------------+------+-----+---------+----------------+


So that the ID of any P entity (1-6) would go in the 'pid' column. The 'ptype' column would contain, ie, "p1", "p2", "p3" etc... In other words, we would store in the table the type and id of the P entity related to this description.

Is there any way in hibernate to mimic this sort of setup?

Thanks!


Top
 Profile  
 
 Post subject:
PostPosted: Thu Mar 24, 2005 8:39 pm 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 6:10 am
Posts: 8615
Location: Neuchatel, Switzerland (Danish)
i cant follow why you want type (called discriminator) both on the table and the foreign key references.

but anyhow, if its for looking up different types from the same id (and those types are not mapped in a hiearchy) you could look at the <any> reference hibernate supports.


if its just to be redundant then you could probably easily manage this by writing a usertype that in addition to the foreignkey wrote the type.

_________________
Max
Don't forget to rate


Top
 Profile  
 
 Post subject:
PostPosted: Fri Mar 25, 2005 1:50 pm 
Beginner
Beginner

Joined: Sun Feb 20, 2005 12:14 am
Posts: 49
The trouble is that if we have just one "pid" foreign key in the Description table, then hibernate has no way to know which type of P object this description is associated with. We might have a P1, a P3, and a P6 all with the ID 27. If Description.pid = 27, how do we know which of the three it belongs to? In order to solve this, I only see two approaches:

    Use a different foreign key field for each type of P (this works)
    Use a "discriminator" column of some type to tell us which P type we're related to (we can't find a way to do it like this in hibernate)


We will look at the <any> concept and see if that solves it for us. Here's hoping :)

Thanks,

Geoff


Top
 Profile  
 
 Post subject:
PostPosted: Fri Mar 25, 2005 2:47 pm 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 6:10 am
Posts: 8615
Location: Neuchatel, Switzerland (Danish)
ah - i had it turned upside down (P1 and P2 are really baad example names)

yes <any> is what you want.

_________________
Max
Don't forget to rate


Top
 Profile  
 
 Post subject:
PostPosted: Fri Mar 25, 2005 2:58 pm 
Beginner
Beginner

Joined: Sun Feb 20, 2005 12:14 am
Posts: 49
We now have it sort of half-way working. We use this mapping in Description:

Code:
        <any name="entity" id-type="long">
            <meta-value class="com.am.t.beans.P1" value="P1"/>
            <meta-value class="com.am.t.beans.P2" value="P2"/>
            <column name="entityType"/>
            <column name="entityId"/>
        </any>


If we leave it just like this, and we insert a Description directly, it seems to work right. Hibernate creates an entityType column and an entityId column and it sets entityType properly based on the "entity" property in the Description object.

We have two problems still though.

First, it uses the fully qualified object name in the entityType column instead of "P1" and "P2." My understanding was that our <meta-value> elements should have taken care of that.

Also, each P1 and P2 is associated with many descriptions. We add <map> elements to these classes to make these collections work:

Code:
<hibernate-mapping>
    <class name="com.am.t.beans.P1" table="p1">
        <id name="id" unsaved-value="0">
                <generator class="native"/>
        </id>

       <version name="version" type="calendar" unsaved-value="null"/>
       
        <property name="name" type="string"/>
       
        <map name="descriptions"
            lazy="true"
            cascade="all">
            <key column="entityId"/>
            <map-key formula="type" type="string"/>
            <one-to-many class="com.am.t.beans.Description"/>
        </map>
       
      </class>

    <class name="com.am.t.beans.P2" table="p2">
        <id name="id" unsaved-value="0">
                <generator class="native"/>
        </id>

       <version name="version" type="calendar" unsaved-value="null"/>
       
        <property name="name" type="string"/>
       
        <map name="descriptions"
            lazy="true"
            cascade="all">
            <key column="entityId"/>
            <map-key formula="type" type="string"/>
            <one-to-many class="com.am.t.beans.Description"/>
        </map>
       
      </class>
</hibernate-mapping>


When we add the <map> collection, Hibernate adds foreign key constraints to the Description table so that description.entityId has to match an id in both P1 and P2 so we get foreign key constraint violations. If it matters, we're really trying to get it so that we can persist a P1 or P2 and have this cascaded to the contained descriptions automatically. In other words, the P1 and P2 objects "own" their descriptions.

Any more guidance would be great!

Geoff


Top
 Profile  
 
 Post subject: Resolved?
PostPosted: Fri Mar 25, 2005 3:31 pm 
Beginner
Beginner

Joined: Sun Feb 20, 2005 12:14 am
Posts: 49
Ok, things seem to be working now. To get our discriminator columns to use our <meta-value>'s properly, we added "meta-type='string'" to the <any> element. This makes sense.

Also, and this time we're just guessing wildly, we fixed our foreign-key constraint problem by modifying our <map> sections thusly:

Code:
<map
   name="descriptions"
   lazy="true"
   cascade="all">
   <key column="entityId" foreign-key="none"/>
   <map-key formula="type" type="string"/>
   <one-to-many class="com.am.t.beans.Description"/>
</map>


The only change is the addition of "foreign-key='none'" to the <key> element. I have no idea if "none" is actually an appropriate value, but it did cause Hibernate to stop creating foreign key constraints on the entityId column.

Did this work because there is no column called "none" or because Hibernate actually recognizes "none" as a special case in the foreign-key attribute? We could find no documentation on the foreign-key attribute with respect to the <key> element.

Geoff


Top
 Profile  
 
 Post subject:
PostPosted: Fri Mar 25, 2005 4:03 pm 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 6:10 am
Posts: 8615
Location: Neuchatel, Switzerland (Danish)
yes - none is actually a newly added still not documented "disable foreign key" creation feature ,)

i would appreciate if you poste a jira about this "hibernate making a foreign key which actually isn't correct because of an <any>" to the JIRA.

Maybe it will be turned down by a "use foreign-key='none'" but maybe we can do someting to deduce that foreignkey constraint is "wrong"

_________________
Max
Don't forget to rate


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