I have a question about JPA-2.0 (provider is Hibernate) relationships and their corresponding management in Java. Let's assume i have a Department and an Employee entity:
@Entity
public class Department {
...
@OneToMany(mappedBy = "department")
private Set<Employee> employees = new HashSet<Employee>();
...
}
@Entity
public class Employee {
...
@ManyToOne(targetEntity = Department.class)
@JoinColumn
private Department department;
...
}
Now i know i have to manage the Java relationships myself, as in the following unit test:
@Transactional
@Test
public void testBoth() {
Department d = new Department();
Employee e = new Employee();
e.setDepartment(d);
d.getEmployees().add(e);
em.persist(d);
em.persist(e);
assertNotNull(em.find(Employee.class, e.getId()).getDepartment());
assertNotNull(em.find(Department.class, d.getId()).getEmployees());
}
If i leave out either e.setDepartment(d)
or d.getEmployees().add(e)
the assertions will fail. So far, so good. What if i commit the database transaction in between?
@Test
public void testBoth() {
EntityManager em = emf.createEntityManager();
em.getTransaction().begin();
Department d = new Department();
Employee e = new Employee();
e.setDepartment(d);
d.getEmployees().add(e);
em.persist(d);
em.persist(e);
em.getTransaction().commit();
em.close();
em = emf.createEntityManager();
em.getTransaction().begin();
assertNotNull(em.find(Employee.class, e.getId()).getDepartment());
assertNotNull(em.find(Department.class, d.getId()).getEmployees());
em.getTransaction().commit();
em.close();
}
Do i still need to manage both sides of the relation? No, as it turns out, i don't have to. With this modification
e.setDepartment(d);
//d.getEmployees().add(e);
the assertions still succeed. However, if i only set the other side:
//e.setDepartment(d);
d.getEmployees().add(e);
the assertions fail. Why? Is is because the Employee is the owning side of the relation? Can i change that behavior by annotating differently? Or is it just always the "One" side of the "OneToMany" that determines when the foreign key field in the database is filled?