JPA:关于OneToMany关系中阻抗不匹配的问题 [英] JPA: question on impedance mismatch in OneToMany relations

查看:212
本文介绍了JPA:关于OneToMany关系中阻抗不匹配的问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个关于JPA-2.0(提供者是Hibernate)关系及其在Java中的相应管理的问题。假设我有一个部门和一个雇员实体:

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

现在我知道我必须管理Java关系我自己,如下面的单元测试:

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

如果我遗漏 e.setDepartment(d ) d.getEmployees()。add(e)断言将失败。到现在为止还挺好。如果我在其间提交数据库事务怎么办?

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);

断言失败。为什么?是因为员工是关系的拥有者吗?我可以通过不同的注释来改变这种行为吗?或者只是OneToMany的One一侧确定数据库中的外键字段何时被填充?

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?

推荐答案

JPA中的实体关系具有拥有和反面。数据库更新由拥有方的状态决定。在您的情况下, Employee 是一个拥有方,因为 mappedBy 属性。

Entity relationships in JPA have owning and inverse sides. Database updates are determined by the state of the owning side. In your case Employee is an owning side due to the mappedBy attribute.

来自 JPA 2.0规范


2.9实体关系

...

关系可以是双向的,也可以是
单向的。双向
关系既有拥有方
又有反向(非拥有)方。
单向关系只有
的拥有方。
关系的拥有方确定数据库中关系
的更新,如
3.2.4节中描述的

Relationships may be bidirectional or unidirectional. A bidirectional relationship has both an owning side and an inverse (non-owning) side. A unidirectional relationship has only an owning side. The owning side of a relationship determines the updates to the relationship in the database, as described in section 3.2.4.

以下规则适用于双向关系:

The following rules apply to bidirectional relationships:


  • a的反面双向
    关系必须通过使用
    ,OneToOne,OneToMany或ManyToMany
    注释的mappedBy元素来引用其拥有的
    方。 mappedBy元素

    中指定属性或字段,该实体是
    关系的所有者。


  • 一对多/多对一
    双向关系的多方必须是
    拥有方,因此mappedBy
    元素不能在
    ManyToOne注释中指定。

  • 对于
    一对一双向
    关系,拥有方
    对应于包含
    对应外键的一方。

  • 对于
    多对多双向
    关系,任何一方可能是
    拥有方。

  • The inverse side of a bidirectional relationship must refer to its owning side by use of the mappedBy element of the OneToOne, OneToMany, or ManyToMany annotation. The mappedBy element designates the property or field in the entity that is the owner of the relationship.
  • The many side of one-to-many / many-to-one bidirectional relationships must be the owning side, hence the mappedBy element cannot be specified on the ManyToOne annotation.
  • For one-to-one bidirectional relationships, the owning side corresponds to the side that contains the corresponding foreign key.
  • For many-to-many bidirectional relationships either side may be the owning side.

这篇关于JPA:关于OneToMany关系中阻抗不匹配的问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆