如何级联仅保留新实体

2024-01-02

我无法弄清楚如何为以下实体正确设置 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(使用前将#替换为@)

如何级联仅保留新实体 的相关文章

随机推荐