JPA: Frage zu Impedanzfehlanpassung in OneToMany-Beziehungen

Ich habe eine Frage zu JPA-2.0-Beziehungen (Anbieter ist Hibernate) und deren entsprechender Verwaltung in Java. Nehmen wir an, ich habe eine Abteilung und eine Mitarbeiter-Entität:

@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;
  ...
}

Jetzt weiß ich, dass ich die Java-Beziehungen selbst verwalten muss, wie im folgenden 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());
}

Wenn ich entweder auslassee.setDepartment(d) oderd.getEmployees().add(e) Die Zusicherungen werden fehlschlagen. So weit, ist es gut. Was passiert, wenn ich die Datenbanktransaktion zwischenzeitlich festschreibe?

@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();
}

Muss ich immer noch beide Seiten der Beziehung verwalten? Nein, wie sich herausstellt, muss ich nicht. Mit dieser Änderung

e.setDepartment(d);
//d.getEmployees().add(e);

die Behauptungen sind immer noch erfolgreich. Wenn ich jedoch nur die andere Seite einstelle:

//e.setDepartment(d);
d.getEmployees().add(e);

die Behauptungen scheitern. Warum? Liegt es daran, dass der Mitarbeiter die besitzende Seite der Beziehung ist? Kann ich dieses Verhalten ändern, indem ich anders annotiere? Oder bestimmt nur immer die "Eins" -Seite von "OneToMany", wann das Fremdschlüsselfeld in der Datenbank gefüllt ist?

Antworten auf die Frage(6)

Ihre Antwort auf die Frage