| Author |
Ternary and composite ID
|
Lilly Wiesie
Greenhorn
Joined: Jan 20, 2005
Posts: 26
|
|
I am working on ternary relationship using composite ID: Table TernayA - PK: TernaryAID Table TernaryB - PK: TernaryBID Table TernaryC - PK: TernaryCID Table TernaryAll - composite key: TernaryAID, TernaryBID, TernaryCID (which maps to the PK in tables TernarA, TernaryB, and TernaryC). Here are the mapping files: TernaryA.hbm.xml ---------------- <?xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 2.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd" > <hibernate-mapping> <!-- Created by the Middlegen Hibernate plugin 2.1 http://boss.bekk.no/boss/middlegen/ http://www.hibernate.org/ --> <class name="com.tietronix.hbn.dal.TernaryA" table="TernaryA" dynamic-update="true" dynamic-insert="true" select-before-update="true" > <id name="ternaryAid" type="java.lang.Integer" column="TernaryAID" unsaved-value="0" > <generator class="identity" /> </id> <property name="ternaryAdesc" type="java.lang.String" column="TernaryADesc" length="50" /> <!-- Associations --> <!-- bi-directional one-to-many association to TernaryAll --> <set name="ternaryAlls" lazy="true" inverse="true" cascade="all" > <key> <column name="TernaryAID" /> </key> <one-to-many class="com.tietronix.hbn.dal.TernaryAll" /> </set> </class> </hibernate-mapping> ======================================================================== TernaryB.hbm.xml: ----------------- <?xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 2.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd" > <hibernate-mapping> <!-- Created by the Middlegen Hibernate plugin 2.1 http://boss.bekk.no/boss/middlegen/ http://www.hibernate.org/ --> <class name="com.tietronix.hbn.dal.TernaryB" table="TernaryB" dynamic-update="true" dynamic-insert="true" select-before-update="true" > <id name="ternaryBid" type="java.lang.Integer" column="TernaryBID" unsaved-value="0" > <generator class="identity" /> </id> <property name="ternaryBdesc" type="java.lang.String" column="TernaryBDesc" length="50" /> <!-- Associations --> <!-- bi-directional one-to-many association to TernaryAll --> <set name="ternaryAlls" lazy="true" inverse="true" cascade="all" > <key> <column name="TernaryBID" /> </key> <one-to-many class="com.tietronix.hbn.dal.TernaryAll" /> </set> </class> </hibernate-mapping> ============================================================ TerberyC.hbm.xml: ----------------- <?xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 2.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd" > <hibernate-mapping> <!-- Created by the Middlegen Hibernate plugin 2.1 http://boss.bekk.no/boss/middlegen/ http://www.hibernate.org/ --> <class name="com.tietronix.hbn.dal.TernaryC" table="TernaryC" dynamic-update="true" dynamic-insert="true" select-before-update="true" > <id name="ternaryCid" type="java.lang.Integer" column="TernaryCID" unsaved-value="0" > <generator class="identity" /> </id> <property name="ternaryCdesc" type="java.lang.String" column="TernaryCDesc" length="50" /> <!-- Associations --> <!-- bi-directional one-to-many association to TernaryAll --> <set name="ternaryAlls" lazy="true" inverse="true" cascade="all" > <key> <column name="TernaryBID" /> </key> <one-to-many class="com.tietronix.hbn.dal.TernaryAll" /> </set> </class> </hibernate-mapping> ====================================================== TernaryAll.hbm.xml: ------------------- <?xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 2.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd" > <hibernate-mapping> <!-- Created by the Middlegen Hibernate plugin 2.1 http://boss.bekk.no/boss/middlegen/ http://www.hibernate.org/ --> <class name="com.tietronix.hbn.dal.TernaryAll" table="TernaryAll" > <composite-id> <key-property name="ternaryAid" column="TernaryAID" type="int" length="10" /> <key-property name="ternaryBid" column="TernaryBID" type="int" length="10" /> <key-property name="ternaryCid" column="TernaryCID" type="int" length="10" /> </composite-id> <many-to-one name="ternaryA" cascade="all" class="com.tietronix.hbn.dal.TernaryA" not-null="true" insert="false" update="false" > <column name="TernaryAID" /> </many-to-one> <many-to-one name="ternaryB" cascade="all" class="com.tietronix.hbn.dal.TernaryB" not-null="true" insert="false" update="false" > <column name="TernaryBID" /> </many-to-one> <many-to-one name="ternaryC" cascade="all" class="com.tietronix.hbn.dal.TernaryC" not-null="true" insert="false" update="false" > <column name="TernaryCID" /> </many-to-one> </class> </hibernate-mapping> =============================================== Here is the testing jsp: <%@page contentType="text/html"%> <%@page pageEncoding="UTF-8"%> <%@page import="org.hibernate.*"%> <%@page import="com.tietronix.hbn.dal.*"%> <%@page import="com.tietronix.hbn.util.*"%> <%@page import="java.util.*"%> <html> <head><title>JSP Page</title></head> <body> <% org.hibernate.Session session2 = hbnUtil.currentSession(); Transaction tx = session2.beginTransaction(); TernaryA tbA = new TernaryA(); tbA.setTernaryAdesc("John"); TernaryB tbB = new TernaryB(); tbB.setTernaryBdesc("Tomato Juice"); TernaryC tbC = new TernaryC(); tbC.setTernaryCdesc("too much"); TernaryAll tbAll = new TernaryAll(); Set mSet = new HashSet(); mSet.add ( tbAll ); tbA.setTernaryAlls( mSet ); tbB.setTernaryAlls( mSet ); tbC.setTernaryAlls( mSet ); tbAll.setTernaryA( tbA ); tbAll.setTernaryB( tbB ); tbAll.setTernaryC(tbC); session2.save(tbA); session2.save( tbB ); session2.save( tbC ); session2.flush(); tx.commit(); hbnUtil.closeSession(); %> Test completed </body> </html> The records did get saved for TernaryA, TernaryB, and TernaryC. But nothing was saved in table TernaryAll, did I miss something? Also what will be a better way to handle ternary relationship in Hibernate? I actually have a table that has a composite key containing four columns (three as foreign keys, and the last one is some assigned value). Thanks. Lilly
|
 |
David Harkness
Ranch Hand
Joined: Aug 07, 2003
Posts: 1646
|
|
The only thing that looks suspect to me is giving the A, B and C objects the same Set of TernaryAlls. It probably doesn't make a difference in this case since you're just creating and saving the objects, but it will cause issues later if you have continue adding more objects or use a second-level cache. For example, if you added a new TernaryAll that linked to TernaryA and two new TernaryB and TernaryC instances, the original TernaryB and TernaryC would get the new TernaryAll added to their Set since it's the same Set that TernaryA has. I only know that the Hibernate developers will tell you again and again not to use composite IDs, and I can say from a database and general ORM point-of-view that they are a major PITA. If you can create a surrogate key for that table, it will be much easier. Okay, reading the Hibernate mapping docs for composite-id I notice that it says there are two types of columns: key-property and key-many-to-one. Have you tried using the latter as it seems to be what you'd want? As for more information on ternary (and more) associations, the Hibernate docs briefly mention ternary associations.
|
 |
Lilly Miaqa
Greenhorn
Joined: Jan 25, 2005
Posts: 8
|
|
Dave, Thanks. Looks like I need to search alternative ways to implement the ternary relationship. That's a good advice on not using the composite key. I'll keep it in mind. Lilly
|
 |
 |
|
|
subject: Ternary and composite ID
|
|
|