gpt4 book ai didi

java - 如何级联仅保留新实体

转载 作者:搜寻专家 更新时间:2023-11-01 01:13:44 24 4
gpt4 key购买 nike

我无法确定如何为以下实体正确设置 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);

通过在@ManyToMany 上设置cascadeType.PERSIST,这工作得很好。但是,如果公司列表包含一个预先保留的公司,我会得到一个 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。所以是的,如果您对用户调用持久化,那么它将对每个子级调用持久化,无论它们是否被持久化。

这种情况不能用级联来理想地处理。 Cascade persist 适用于所有子级都与父级一起创建的情况(例如,如果使用具有“技能”列表)并且更适用于一对多。

在这种情况下,我个人不会使用级联。在不需要时公然使用级联会降低应用程序的速度。

如果您觉得必须使用级联,则可以使用级联合并。合并将在实体尚未持久化时持久化实体。但是,merge 有一些非常奇怪的副作用,这可能就是您没有注意到它起作用的原因。考虑以下示例:

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

关于java - 如何级联仅保留新实体,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12494288/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com