I have read several documents, but have not seen a complete example useing the many-to-many composit-element.
1. It seems odd that I have to insert the parent and then child and then establish the associations. Have I done this correctly? See my Junit test below.
2. I can read the parent and find all of the children. But I cannot get a mapping to work that will let me read the child to find all of the parents. I am hopeful that this is possible. Or do I need to map using the Entity class structure?
Mappings:
<?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>
<class name="test.this.core.test.domain.Parent" table="TEST_TABLE_PARENT"
persister="test.this.core.persistence.SpectrumPersister" >
<id name="id" type="java.lang.Long" column="PARENT_ID" unsaved-value="null">
<generator class="native">
<param name="sequence">TEST_ID_SEQUENCE</param>
</generator>
</id>
<version name="updateCount" type="integer" column="UPDATE_COUNT"/>
<property name="description" >
<column name="DESCRIPTION" not-null="true"/>
</property>
<bag name="associations" table="TEST_TABLE_ASSOCIATION" lazy="true">
<key column="PARENT_ID"/>
<composite-element class="test.this.core.test.domain.ParentChildAssociation">
<property name="type"/>
<many-to-one name="child" column="CHILD_ID" class="test.this.core.test.domain.Child"/>
</composite-element>
</bag>
</class>
</hibernate-mapping>
<?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>
<class name="test.this.core.test.domain.Child" table="TEST_TABLE_CHILD"
persister="test.this.core.persistence.SpectrumPersister" >
<id name="id" type="java.lang.Long" column="CHILD_ID" unsaved-value="null">
<generator class="native">
<param name="sequence">TEST_ID_SEQUENCE</param>
</generator>
</id>
<version name="updateCount" type="integer" column="UPDATE_COUNT"/>
<property name="description" >
<column name="DESCRIPTION" not-null="true"/>
</property>
<!-- ??? -->
<!--bag name="associations" inverse="true" cascade="all">
<key column="CHILD_ID"/>
<one-to-many class="test.this.core.test.domain.ParentChildAssociation"/>
</bag-->
</class>
</hibernate-mapping>
Classes:
package test.this.core.test.domain;
import java.util.ArrayList;
import java.util.List;
import test.this.framework.persistence.Entity;
public class Parent extends Entity {
private String description;
private List associations = new ArrayList();
public List getAssociations() {
return associations;
}
public void setAssociations(List associations) {
this.associations = associations;
}
public void addAssociation(ParentChildAssociation association) {
associations.add(association);
}
public boolean removeAssociation(ParentChildAssociation association) {
return getAssociations().remove(association);
}
public Parent() {
}
public Parent(String description) {
this.description = description;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String toString() {
return toEntityString();
}
}
package test.this.core.test.domain;
import java.util.ArrayList;
import java.util.List;
import test.this.core.account.domain.ChargeOff;
import test.this.framework.persistence.Entity;
public class Child extends Entity {
private String description;
private List associations = new ArrayList();
public Child() {
}
public Child(String description) {
this.description = description;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String toString() {
return toEntityString();
}
public List getAssociations() {
return associations;
}
public void setAssociations(List parents) {
this.associations = parents;
}
public void addAssociation(ParentChildAssociation association) {
associations.add(association);
}
public boolean removeAssociation(ParentChildAssociation association) {
return getAssociations().remove(association);
}
}
package test.this.core.test.domain;
public class ParentChildAssociation {
private Parent parent;
private Child child;
private String type;
public ParentChildAssociation() {
}
public ParentChildAssociation(Parent parent, Child child, String type) {
this.parent = parent;
this.child = child;
this.type = type;
}
public Child getChild() {
return child;
}
public void setChild(Child child) {
this.child = child;
}
public Parent getParent() {
return parent;
}
public void setParent(Parent parent) {
this.parent = parent;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
}
Junit Test:
package test.this.core.test.test;
import java.util.Iterator;
import java.util.List;
import junit.framework.TestCase;
import test.this.core.persistence.GenericDAO;
import test.this.core.persistence.HibernateTestTxBroker;
import test.this.core.test.domain.Child;
import test.this.core.test.domain.Parent;
import test.this.core.test.domain.ParentChildAssociation;
import test.this.framework.logging.Logger;
public class ParentDAOTest extends TestCase {
private static final Logger logger = Logger.getLogger(ParentDAOTest.class);
private Transaction tx;
private GenericDAO dao = new GenericDAO();
public void testManyToManyCompositeElemtnt() throws Exception {
logger.debug("setUp()");
tx = HibernateTestTxBroker.beginTransaction();
// add parent Mother
Parent mother = new Parent("Mother");
dao.insert(mother);
// add parent Father1
Parent father1 = new Parent("Father1");
dao.insert(father1);
// add parent Father2
Parent father2 = new Parent("Father2");
dao.insert(father2);
// add kid1
Child kid1 = new Child("Kid1");
dao.insert(kid1);
// add kid2
Child kid2 = new Child("Kid2");
dao.insert(kid2);
//associate mother to her 2 biological kids
mother.addAssociation(new ParentChildAssociation(mother, kid1, "Biolological Parent"));
mother.addAssociation(new ParentChildAssociation(mother, kid2, "Biolological Parent"));
dao.update(mother);
//associate father1 to his one biological kid1
father1.addAssociation(new ParentChildAssociation(father1, kid1, "Biolological Parent"));
dao.update(father1);
//associate father2 to kid1 as step father and kid2 as biological father.
father2.addAssociation(new ParentChildAssociation(father2, kid1, "Step Parent"));
father2.addAssociation(new ParentChildAssociation(father2, kid2, "Biolological Parent"));
dao.update(father2);
reopenSession();
//Read mother and verify she has 2 children (kdi1 and kid2)
Parent tempMother = (Parent) dao.read(mother.getId(), Parent.class);
List associations = tempMother.getAssociations();
assertEquals(2,associations.size());
for (int i=0; i<associations.size(); i++) {
ParentChildAssociation association = (ParentChildAssociation) associations.get(i);
if (association.getChild().getDescription().equalsIgnoreCase("kid1") ||
association.getChild().getDescription().equalsIgnoreCase("kid2")){
// do nothing
}else fail("this should not be happening" + association.getChild().getDescription());
}
reopenSession();
//Read kid2 and verify he has 2 fathers (one biological and one step)
Child tempKid2 = (Child) dao.read(kid2.getId(), Child.class);
associations = tempKid2.getAssociations();
assertEquals(2,associations.size());
for (int i=0; i<associations.size(); i++) {
ParentChildAssociation association = (ParentChildAssociation) associations.get(i);
if (association.getParent().getDescription().equalsIgnoreCase("Father1") ||
association.getParent().getDescription().equalsIgnoreCase("Father2")){
// do nothing
}else fail("this should not be happening" + association.getChild().getDescription());
}
}
private void reopenSession() throws Exception{
tx.commit();
dao.close();
tx = HibernateTestTxBroker.beginTransaction();
}
}
|