Hi All, after a couple of weeks of struggling & reading various documentation & posts here, I am on my final attempt to get many-to-many relationships to work. In the following code there is some commented out code. The test runs fine with the code commented out. There are three different versions of the commented out code, all trying to do the same thing. If any of these blocks are uncommented, the test will fail at the line
assertTrue(parents.contains(parent)); & I can not understand why.
Please, please, please can some kind soul explain to me why this is happening & how I can fix it. I have read all of the docs I can find on Parent/Child relationships, searched this forum repeatedly, searched Google, posted here a couple of times & I'm still hitting the same problem :-( Maybe I'm being dumb, but I just seem to have a blind spot here & cannot get past it. I cannot afford to waste too much more time on this project & will have to go back to CMP if I don't get it working soon. Please could somebody point out my error here, preferably by showing how they would change this code to work.
Eternally grateful for any help :-)
Paul
(code follows)
JUnit Test
Code:
import junit.framework.TestCase;
import net.sf.hibernate.Session;
import net.sf.hibernate.HibernateException;
import net.sf.hibernate.Transaction;
import java.util.HashSet;
import java.util.Set;
import java.util.Iterator;
/**
* Date: 21-Jul-2004
*/
public class HibernateTestTwo extends TestCase {
public void testParentChild(){
try {
Session session = null;
Transaction tx = null;
try {
//create parent
session = HibernateSessionFactory.getSession();
tx = session.beginTransaction();
Parent parent = new Parent("DAD",new HashSet());
session.save(parent);
tx.commit();
session.close();
// add child
Child child = new Child("KATHERINE",new HashSet(),new HashSet());
session = HibernateSessionFactory.getSession();
tx = session.beginTransaction();
child.getParents().add(parent);
parent.getChildren().add(child);
session.save(child);
tx.commit();
session.close();
// check child is there
Set children = parent.getChildren();
assertTrue(children.size() == 1);
assertTrue(children.contains(child));
Iterator iterator = children.iterator();
Child childFromParent = null;
if (iterator.hasNext()) {
childFromParent = (Child) iterator.next();
}
assertEquals(child,childFromParent);
// now change Parent name
// parent.setName("MUM");
// session = HibernateSessionFactory.getSession();
// tx = session.beginTransaction();
// session.update(parent);
// session.update(child);
// tx.commit();
// session.close();
// now change Parent name - attempt two
// Set parents = child.getParents();
// iterator = parents.iterator();
// if (iterator.hasNext()) {
// parent = (Parent) iterator.next();
// }
// parent.setName("MUM");
// session = HibernateSessionFactory.getSession();
// tx = session.beginTransaction();
// session.update(parent);
// session.update(child);
// tx.commit();
// session.close();
// now change Parent name - attempt three
// parent.setName("MUM");
// session = HibernateSessionFactory.getSession();
// tx = session.beginTransaction();
// child.getParents().add(parent);
// session.update(child);
// tx.commit();
// session.close();
// now check to see if Parent contains Child & vv
children = parent.getChildren();
assertTrue(children.contains(child));
Set parents = child.getParents(); //swap when using different version of rename above
// parents = child.getParents();
assertTrue(parents.contains(parent));
// delete parent
Integer parentId = parent.getId();
Integer childId = child.getId();
session = HibernateSessionFactory.getSession();
tx = session.beginTransaction();
session.delete(parent);
tx.commit();
session.close();
// ensure parent & child have been deleted
session = HibernateSessionFactory.getSession();
try {
session.load(Parent.class, parentId);
fail("This object should no longer exist");
}
catch (HibernateException e) {
assertTrue(true);
}
try {
session.load(Child.class, childId);
fail("This object should no longer exist");
}
catch (HibernateException e) {
assertTrue(true);
}
session.close();
}
catch(HibernateException e){
tx.rollback();
throw e;
}
finally {
if(session != null){
session.close();
}
}
}
catch (HibernateException e) {
fail(e.getMessage());
}
}
}
Parent config & ClassCode:
<class name="Parent">
<id name="id" type="int">
<generator class="native"/>
</id>
<property name="name" unique="true" type="string"/>
<set name="children" table="parent_child" inverse="true" cascade="all-delete-orphan">
<key column="child_id"/>
<many-to-many column="parent_id" class="Child"/>
</set>
</class>
// default package
import java.io.Serializable;
import java.util.Set;
import org.apache.commons.lang.builder.ToStringBuilder;
/** @author Hibernate CodeGenerator */
public class Parent implements Serializable {
/** identifier field */
private Integer id;
/** nullable persistent field */
private String name;
/** persistent field */
private Set children;
/** full constructor */
public Parent(String name, Set children) {
this.name = name;
this.children = children;
}
/** default constructor */
public Parent() {
}
/** minimal constructor */
public Parent(Set children) {
this.children = children;
}
public Integer getId() {
return this.id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
public Set getChildren() {
return this.children;
}
public void setChildren(Set children) {
this.children = children;
}
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof Parent)) return false;
final Parent parent = (Parent) o;
if (!name.equals(parent.name)) return false;
return true;
}
public int hashCode() {
return name.hashCode();
}
public String toString() {
final StringBuffer buf = new StringBuffer();
buf.append("Parent");
buf.append("{id=").append(id);
buf.append(",name=").append(name);
buf.append('}');
return buf.toString();
}
}
Child config & ClassCode:
<class name="Child">
<id name="id" type="int" unsaved-value="0" >
<generator class="native"/>
</id>
<property name="name" unique="true" type="string"/>
<set name="parents" table="parent_child" cascade="save-update">
<key column="parent_id"/>
<many-to-many column="child_id" class="Parent"/>
</set>
<set name="grandchildren" table="child_grandchild" inverse="true" cascade="all-delete-orphan">
<key column="grandchild_id"/>
<many-to-many column="child_id" class="Grandchild"/>
</set>
</class>
// default package
import java.io.Serializable;
import java.util.Set;
import org.apache.commons.lang.builder.ToStringBuilder;
/** @author Hibernate CodeGenerator */
public class Child implements Serializable {
/** identifier field */
private Integer id;
/** nullable persistent field */
private String name;
/** persistent field */
private Set parents;
/** persistent field */
private Set grandchildren;
/** full constructor */
public Child(String name, Set parents, Set grandchildren) {
this.name = name;
this.parents = parents;
this.grandchildren = grandchildren;
}
/** default constructor */
public Child() {
}
/** minimal constructor */
public Child(Set parents, Set grandchildren) {
this.parents = parents;
this.grandchildren = grandchildren;
}
public Integer getId() {
return this.id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
public Set getParents() {
return this.parents;
}
public void setParents(Set parents) {
this.parents = parents;
}
public Set getGrandchildren() {
return this.grandchildren;
}
public void setGrandchildren(Set grandchildren) {
this.grandchildren = grandchildren;
}
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof Child)) return false;
final Child child = (Child) o;
if (!name.equals(child.name)) return false;
return true;
}
public int hashCode() {
return name.hashCode();
}
public String toString() {
final StringBuffer buf = new StringBuffer();
buf.append("Child");
buf.append("{name=").append(name);
buf.append(",id=").append(id);
buf.append('}');
return buf.toString();
}
}