I am tring to do a many-to-many mapping exactly like the Category/Item mapping described in Chapter 6 of the Manning book (page 226). In my situation, a Category has a Set of Item objects and the Item class has a Set of Category objects. What makes my situation different, and where I cannot find an answer in any of the forums or google, is that my association table has 3 columns (1 surrogate key and the 2 FKs). Is there a way to map the Category and Item classes
without creating an Association class? here's how it is now (which is wrong b/c the surrogate primary key is not mentioned anywhere):
Hibernate version: 3
Mapping documents:
---------------------------------
Item.hbm.xml
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">
<hibernate-mapping>
<class name="com.Item" table="ITEM" dynamic-update="true" dynamic-insert="true">
<id name="id" column="ITEM_ID">
<generator class="sequence">
<param name="sequence">CATEGORY_SEQ</param>
</generator>
</id>
<version name="version" type="long" column="VERSION" unsaved-value="null"/>
<property name="name" column="NAME"/>
<property name="description" column="DESCRIPTION"/>
<set name="categories" table="CATEGORY_ITEM" inverse="true" lazy="false">
<key column="ITEM_ID"/>
<one-to-many class="com.Category"/>
</set>
</class>
</hibernate-mapping>
----------------------------------------------
Category.hbm.xml
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">
<hibernate-mapping>
<class name="com.Category" table="CATEGORY" dynamic-update="true" dynamic-insert="true">
<id name="id" column="CATEGORY_ID">
<generator class="sequence">
<param name="sequence">CATEGORY_SEQ</param>
</generator>
</id>
<version name="version" type="long" column="VERSION" unsaved-value="null"/>
<property name="name" column="NAME"/>
<set name="items" table="CATEGORY_ITEM" lazy="false" inverse="false">
<key column="CATEGORY_ID" />
<many-to-many class="com.Item"/>
</set>
</class>
</hibernate-mapping>
----------------------------
Category.java
Code:
package com;
import java.util.Set;
import java.util.HashSet;
public class Category
{
private String id, name;
private Set items = new HashSet();
private Long version;
//public getter and setters omitted for brevity
public void addItem(Item item)
{
items.add(item);
item.addCategory(this);
}
}
--------------------
Item.java
Code:
package com;
import java.util.Set;
import java.util.HashSet;
public class Item
{
private String id;
private String name;
private String description;
private Set categories = new HashSet();
private Long version;
//public getter and setters omitted for brevity
public void addCategory(Category category)
{
categories.add(category);
category.addItem(this);
}
}
Table Schema:
CREATE TABLE CATEGORY (
CATEGORY_ID VARCHAR2(30) NOT NULL,
CATEGORY_NAME VARCHAR2(30) NULL,
VERSION NUMBER(6) NULL
);
ALTER TABLE CATEGORY
ADD ( PRIMARY KEY (CATEGORY_ID) ) ;
CREATE TABLE CATEGORY_ITEM (
CATEGORY_ITEM_ID VARCHAR2(30) NOT NULL,
CATEGORY_ID VARCHAR2(30) NULL,
ITEM_ID VARCHAR2(30) NULL
);
ALTER TABLE CATEGORY_ITEM
ADD ( PRIMARY KEY (CATEGORY_ITEM_ID) ) ;
CREATE TABLE ITEM (
ITEM_ID VARCHAR2(30) NOT NULL,
ITEM_NAME VARCHAR2(30) NULL,
ITEM_DESC VARCHAR2(30) NULL,
VERSION NUMBER(6) NULL
);
ALTER TABLE ITEM
ADD ( PRIMARY KEY (ITEM_ID) ) ;
ALTER TABLE CATEGORY_ITEM
ADD ( FOREIGN KEY (ITEM_ID)
REFERENCES ITEM ) ;
ALTER TABLE CATEGORY_ITEM
ADD ( FOREIGN KEY (CATEGORY_ID)
REFERENCES CATEGORY ) ;
Full stack trace of any exception that occurs:
The entire stack trace is: java.lang.StackOverflowError
This makes sense because obviously Hibernate has no way of knowing what the true priamry key is on the association table (i.e. CATEGORY_ITEM_ID). I know I could remove the surrogate primary key on the association table and make a constraint that the 2 foreign keys are the unique primary key, but due to politcal reasons, I cannot change the existing association table.
Database: Oracle 10G Express