J'ai une question sur les relations JPA-2.0 (le fournisseur est Hibernate) et leur gestion correspondante en Java. Supposons que j'ai un département et une entité de l'employé:JPA: question sur l'incompatibilité d'impédance dans les relations OneToMany
@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;
...
}
Maintenant, je sais que je dois gérer les relations Java moi-même, comme dans le test unitaire suivant:
@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());
}
Si je laisse de côté soit e.setDepartment(d)
ou d.getEmployees().add(e)
les assertions échoueront. Jusqu'ici tout va bien. Que faire si je valide la transaction de la base de données entre?
@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();
}
Dois-je encore gérer les deux côtés de la relation? Non, il s'avère que je n'ai pas à le faire. Avec cette modification
e.setDepartment(d);
//d.getEmployees().add(e);
les assertions réussissent encore. Cependant, si je ne place que l'autre côté:
//e.setDepartment(d);
d.getEmployees().add(e);
les assertions échouent. Pourquoi? Est-ce parce que l'employé est le côté propriétaire de la relation? Puis-je changer ce comportement en annotant différemment? Ou est-ce toujours le côté "One" de "OneToMany" qui détermine quand le champ de clé étrangère dans la base de données est rempli?
Vous créez une nouvelle EM via 'em.close(); em = emf.createEntityManager(); ', ce qui affecte beaucoup les choses. Essayez d'utiliser une transaction sans créer de nouvelle EM. –