I am trying to set up a one to many bidirectional relationship where the foreign key is part of the primary key. I have managed to set up the annotations to correctly create the tables and populate the database. I can also navigate from the many side to the one side using the appropriate getter method. However, when I try to navigate from the one side to the many side I always get an empty collection back. Any help would be much appreciated.
One side
Code:
package com.jpa.test;
import java.util.*;
import javax.persistence.*;
@Entity
public class Parent {
@Id
private int parentId;
private String parentDescription;
@OneToMany(cascade = CascadeType.ALL, mappedBy = "parent")
private List<Child> children;
public Parent() {
children = new ArrayList<Child>();
}
public Parent(int parentId, String parentDescription) {
this.parentId = parentId;
this.parentDescription = parentDescription;
children = new ArrayList<Child>();
}
public int getParentId() {
return parentId;
}
public void setParentId(int parentId) {
this.parentId = parentId;
}
public String getParentDescription() {
return parentDescription;
}
public void setParentDescription(String parentDescription) {
this.parentDescription = parentDescription;
}
public List<Child> getChildren() {
return children;
}
public void setChildren(List<Child> children) {
this.children = children;
}
@Override
public String toString() {
StringBuffer toStringValue = new StringBuffer().append("Parent[");
toStringValue.append(parentId).append('.');
toStringValue.append(parentDescription).append(']');
return toStringValue.toString();
}
}
Many sideCode:
package com.jpa.test;
import javax.persistence.*;
@Entity
@IdClass(ChildPK.class)
public class Child {
@Id
private int parentId;
@Id
private int childId;
private String childDescription;
@ManyToOne
@JoinColumn(name = "parentId", nullable = false, updatable = false, insertable = false)
private Parent parent;
public Child() {
}
public Child(Parent parent, int childId, String childDescription) {
parentId = parent.getParentId();
this.childId = childId;
this.childDescription = childDescription;
this.parent = parent;
}
public int getParentId() {
return parentId;
}
public void setParentId(int parentId) {
this.parentId = parentId;
}
public int getChildId() {
return childId;
}
public void setChildId(int childId) {
this.childId = childId;
}
public String getChildDescription() {
return childDescription;
}
public void setChildDescription(String childDescription) {
this.childDescription = childDescription;
}
public Parent getParent() {
return parent;
}
public void setParent(Parent parent) {
this.parent = parent;
}
@Override
public String toString() {
StringBuffer toStringValue = new StringBuffer().append("Child[");
toStringValue.append(parentId).append('.');
toStringValue.append(childId).append('.');
toStringValue.append(childDescription).append(']');
return toStringValue.toString();
}
}
Primary KeyCode:
package com.jpa.test;
import java.io.Serializable;
public class ChildPK implements Serializable {
private static final long serialVersionUID = 3087264008385776228L;
public int parentId;
public int childId;
public ChildPK() {
}
public ChildPK(int parentId, int childId) {
this.parentId = parentId;
this.childId = childId;
}
public int getParentId() {
return parentId;
}
public void setParentId(int parentId) {
this.parentId = parentId;
}
public int getChildId() {
return childId;
}
public void setChildId(int childId) {
this.childId = childId;
}
@Override
public int hashCode() {
int hashCode = 0;
hashCode += parentId;
hashCode += childId;
return hashCode;
}
@Override
public boolean equals(Object obj) {
if (!(obj instanceof ChildPK)) {
return false;
}
ChildPK pk = (ChildPK) obj;
boolean eq = true;
if (obj == null) {
eq = false;
} else {
eq = eq && parentId == pk.parentId;
eq = eq && childId == pk.childId;
}
return eq;
}
@Override
public String toString() {
StringBuffer toStringValue = new StringBuffer().append('[');
toStringValue.append(parentId).append('.');
toStringValue.append(childId).append(']');
return toStringValue.toString();
}
}
Test CodeCode:
package com.jpa.test;
import java.util.List;
import javax.persistence.*;
import org.apache.log4j.*;
public class Test {
/**
* Log4j Logger for this class
*/
private static final Logger log = Logger.getLogger(Test.class);
public void doStuff() {
log.debug("inside doStuff()");
// create entity manager
EntityManagerFactory emf = Persistence.createEntityManagerFactory("Scratchpad");
EntityManager em = emf.createEntityManager();
log.debug("created EntityManager");
// start transaction
EntityTransaction transaction = em.getTransaction();
transaction.begin();
log.debug("started transaction");
Parent p1 = new Parent(1, "Parent one");
em.persist(p1);
Child c1 = new Child(p1, 1, "Child one of parent one");
em.persist(c1);
Child c2 = new Child(p1, 2, "Child two of parent one");
em.persist(c2);
// commit transaction
transaction.commit();
log.debug("committed transaction");
// start transaction
transaction = em.getTransaction();
transaction.begin();
log.debug("started transaction");
List<Parent> result1 = em.createQuery("SELECT p FROM Parent p").getResultList();
log.debug("got " + result1.size() + " results");
Parent parent = null;
for (Parent p : result1) {
parent = p;
log.debug(p + " " + p.getChildren());
}
List<Child> result2 = em.createQuery("SELECT c FROM Child c").getResultList();
log.debug("got " + result2.size() + " results");
for (Child c : result2) {
log.debug(c + " " + c.getParent());
}
// commit transaction
transaction.commit();
log.debug("committed transaction");
}
public static void main(String[] args) {
PropertyConfigurator.configure("log4j.properties");
Test m = new Test();
m.doStuff();
}
}
On running this I see the following output:
2007-09-26 11:17:08,562 DEBUG com.jpa.test.Test -inside doStuff()
2007-09-26 11:17:11,718 DEBUG com.jpa.test.Test -created EntityManager
2007-09-26 11:17:11,781 DEBUG com.jpa.test.Test -started transaction
2007-09-26 11:17:11,953 DEBUG com.jpa.test.Test -committed transaction
2007-09-26 11:17:11,953 DEBUG com.jpa.test.Test -started transaction
2007-09-26 11:17:12,218 DEBUG com.jpa.test.Test -got 1 results
2007-09-26 11:17:12,218 DEBUG com.jpa.test.Test -Parent[1.Parent one] []
2007-09-26 11:17:12,234 DEBUG com.jpa.test.Test -got 2 results
2007-09-26 11:17:12,249 DEBUG com.jpa.test.Test -Child[1.1.Child one of parent one] Parent[1.Parent one]
2007-09-26 11:17:12,249 DEBUG com.jpa.test.Test -Child[1.2.Child two of parent one] Parent[1.Parent one]