我无法弄清楚如何为以下实体正确设置 JPA 持久性(使用 EclipseLink 和 transaction-type="RESOURCE_LOCAL"):
@Entity
public class User {
// snip various members
@ManyToMany
private List<Company> companies;
public void setCompanies(List<Company> companies) {
this.companies = companies;
}
}
@Entity
public class Company {
// snip various members
}
我想做的是为公司列表设置一个级联,这样,如果列表中存在以前未持久保存的新公司,它将自动与用户一起持久保存:
User newUser = new User();
Company newCompany = new Company();
List<Company> companies = new ArrayList<Company>();
companies.add(newCompany);
newUser.setCompanies(companies);
entityManager.persist(newUser);
通过设置级联类型.PERSIST在@ManyToMany 上,这工作得很好。但是,如果公司列表包含预先保留的公司,我会收到 MySQLIntegrityConstraintViolationException,因为它试图保留(插入)具有相同主键的新公司:
User newUser = new User();
Company oldCompany = companyDAO.find(oldCompanyId);
List<Company> companies = new ArrayList<Company>();
companies.add(oldCompany);
newUser.setCompanies(companies);
entityManager.persist(newUser);
那么应该如何设置才能自动保留新公司,而将现有公司简单地添加到用户-公司映射中呢?
在 hibernate 中考虑级联的最佳方法是,如果您在父级上调用方法 X,那么它将在每个子级上调用方法 X。所以是的,如果您对用户调用 persist,那么它将对每个子级调用 persist,无论它们是否已被持久化。
这种情况不能用级联来理想地处理。级联持久适用于所有子级都是与父级一起创建的情况(例如,如果某个用途具有“技能”列表),并且更适用于一对多。
我个人不会在这种情况下使用级联。在不需要级联时公然使用级联可能会减慢应用程序的速度。
如果您觉得必须使用级联,则可以使用级联合并。当实体尚未持久化时,合并将持久化实体。然而,合并有一些非常奇怪的副作用,这可能就是您没有注意到它起作用的原因。考虑以下示例:
x = new Foo();
y = new Foo();
em.persist(x);
Foo z = em.merge(y);
//x is associated with the persistence context
//y is NOT associated with the persistence context
//z is associated with the persistence context
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)