简短版本:
假设我在父母和孩子之间有一对多的关系。现在在Java代码中,最好的做法是读取父对象(从数据库中获取),并在其中应用一些名为addChild的方法,或者直接创建一个子项并在不读取父项的情况下保留它?
长版
假设我们有这个父母和孩子(来自http://en.wikibooks.org/wiki/Java_Persistence/OneToMany)
@Entity
public class Employee {
@Id
@Column(name="EMP_ID")
private long id;
...
@OneToMany(mappedBy="owner")
private List<Phone> phones;
...
}
@Entity
public class Phone {
@Id
private long id;
...
@ManyToOne(fetch=FetchType.LAZY)
@JoinColumn(name="OWNER_ID")
private Employee owner;
...
}
现在考虑我有一个网页,员工可以在其中添加电话号码。所以我已经拥有父Employee的id,但是我没有完整的Employee对象。
1-我从数据库中获取整个Employee对象(当然是通过JPA映射)。然后我应用方法employee.addPhone(电话)或类似的东西。这导致两个查询。
2-我创建了手机对象,以及一个错误的员工对象,其中只包含员工的ID并且我坚持了吗?
这方面的最佳做法是什么?
答案 0 :(得分:3)
最佳做法是维护协会的双方。这可以确保您不使用不一致的对象图。但是,它可能会降低服务的性能,特别是如果它只是创建一个链接到员工的新电话。实际上,它将加载员工及其所有现有手机的状态。
请注意,JPA只关心关联的所有者方:设置新Phone的员工足以在数据库中创建关联。
如果您选择使用第二个解决方案,则不应创建假的Employee对象。您应该从EntityManager获取Employee引用:
Employee e = em.getReference(Employee.class, employeeId);
Phone phone = new Phone();
phone.setEmployee(e);
em.persist(phone);
getReference()
不会生成任何SQL查询。它返回一个未初始化的代理,这就是您所需要的。优点是,如果方法最终变得更复杂,并调用员工的任何方法,那么将加载员工的实际状态。