JPA在ManyToOne关系中持久化对象

tal*_*tal 6 java entity-relationship hibernate jpa

@OneToMany在我的数据库中有一个公司/员工关系定义为:

@Entity
public class Employee {
   @Id @GeneratedValue(strategy=GenerationType.IDENTITY)
   private long id;
   @ManyToOne @JoinColumn(name="companyid")
   Company company;
   ....
}

@Entity
public class Company {
@Id @GeneratedValue(strategy=GenerationType.IDENTITY)
private long id;

...
}
Run Code Online (Sandbox Code Playgroud)

现在我将一个新创建的员工添加到一个独立的公司.我使用的代码是这样的:

Company company = em1.find(Company.class, 555L);
em1.close();

EntityTransaction et = em2.getTransaction();
et.begin();
Employee employee = new Employee();
employee.company = company;
em2.persist(employee);
et.close();
Run Code Online (Sandbox Code Playgroud)

这项工作可以吗?
hibernate会将公司合并到第二个EntityManager中,还是仅使用其id并持久保存员工对象?
可能会以某种方式复制我的公司对象或者抛出异常,说明数据库中已存在具有相同ID的公司?

axt*_*avt 8

  • 在描述的情况下Company,id将在持久化Employee对象时使用,但Company本身不会被合并(注意这Employee是关系的拥有方)
  • 如果Company是瞬态而不是分离,则会出现"对象引用未保存的瞬态实例"错误
  • 如果cascade = CascadeType.PERSIST使用,您将得到"分离的实体传递给持久化"错误.

来自JPA规范:

如果X是托管实体,则会将其同步到数据库.

  • 对于来自X的关系引用的所有实体Y,如果与Y的关系已使用级联元素值cascade = PERSIST或cascade = ALL进行注释,则将持久化操作应用于Y.
  • 对于来自X的关系引用的任何实体Y,其中与Y的关系未使用级联元素值cascade = PERSIST或cascade = ALL进行注释:
    • 如果Y是新的或被删除,则刷新操作(以及标记为回滚的事务)将抛出IllegalStateException,否则事务提交将失败.
    • 如果分离Y,则语义取决于关系的所有权.如果X拥有该关系,则对该关系的任何更改都将与数据库同步; 否则,如果Y拥有关系,则行为未定义.