Using hibernate 3.0 for the problem below
Hi,
I have managed to create a
many-to-many association between 2
simple classes (Item and Category) using bag with success as below:
Code:
<class name="org.testfuse.model.Item"
table="item">
<id name="id"
column="item_id"
unsaved-value="null">
<generator class="increment">
</generator>
</id>
<bag
name="categories"
table="category_item"
lazy="true"
inverse="true"
cascade="save-update"
>
<key column="item_id">
</key>
<many-to-many
class="org.testfuse.model.Category"
column="category_id"
outer-join="auto"/>
</bag>
<property name="description"
column="description">
</property>
<property name="name"
column="name" not-null="true">
</property>
</class>
<class name="org.testfuse.model.Category" table="category">
<id name="id"
column="category_id" unsaved-value="null">
<generator class="increment">
</generator>
</id>
<property name="description"
column="description">
</property>
<property name="name" column="name"
not-null="true">
</property>
<bag
name="items"
table="category_item"
lazy="true"
cascade="save-update">
<key
column="category_id">
</key>
<many-to-many
class="org.testfuse.model.Item"
column="item_id"
outer-join="auto"/>
</bag>
</class>
Now the problem. My unit test on the
inverse side (i.e. Item)
only works as expected if I didn't establish a bi-directional
reference in the convenient add methods of my pojo as below
i.e.
Code:
class Category {
public void addItem(Item item)
{
items.add(item);
// item.getCategories().add(this);
}
}
class Item {
public void addCategory(Category category)
{
categories.add(category);
// category.getItems().add(this);
}
}
and my unit test
Code:
/**
* Tests for association from Item to Category. Note this tests
* also shows that inverse="true" in the mapping works as the
* Category collection in Item.java doesn't propagate any change
* to the database.
*
*/
public void testItemAndCategory() {
Item item= (Item)dao.getObject(Item.class, itemId);
assertTrue(item.getCategories().isEmpty());
Category cat = new Category();
cat.setName("Hardware");
item.addCategory(cat);
dao.saveObject(item);
dao.flush();
assertNotNull("Expect a database assigned primary key", cat.getId());
Item item2 = (Item)dao.getObject(Item.class, itemId);
/* Note this assert only pass if I comment out the
item.getCategories().add(this); line and
category.getItems().add(this); line
in pojo
*/
assertTrue("Expect no category", item2.getCategories().size() == 0);
}
Now this test only pass if I comment out the line
Code:
item.getCategories().add(this); // from Category.java and
category.getItems().add(this); //from Item.java
Now according to 'Hibernate in Action', I would have expected
establishing a bi-directional references in POJO is necessary.
So what knowledge am I missing???
BTW, dao from testing code above is just
Code:
public class BaseDaoHibernate extends HibernateDaoSupport implements Dao {
protected final Log log = LogFactory.getLog(getClass());
public void saveObject(Object o) {
getHibernateTemplate().saveOrUpdate(o);
}
public Object getObject(Class clazz, Serializable id) {
Object o = getHibernateTemplate().get(clazz, id);
if (o == null) {
throw new ObjectRetrievalFailureException(clazz, id);
}
return o;
}
public List getObjects(Class clazz) {
return getHibernateTemplate().loadAll(clazz);
}
public void removeObject(Class clazz, Serializable id) {
getHibernateTemplate().delete(getObject(clazz, id));
}
public void flush() {
getHibernateTemplate().flush();
getHibernateTemplate().clear();
}
}
Thanks in Advance,
Sam