如何级联只保留新实体 [英] How to cascade persist only new entities

查看:102
本文介绍了如何级联只保留新实体的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我无法确定如何为以下实体正确设置JPA持久性(使用EclipseLink和transaction-type =RESOURCE_LOCAL):

I'm having trouble figuring out how to set up JPA persistence (using EclipseLink and transaction-type="RESOURCE_LOCAL") correctly for the following entities:

@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
}

我要做的是为公司列表设置一个级联,这样,如果一个以前没有的新公司保持在列表中,它将与用户一起自动保存:

What I'm trying to do is set up a cascade for the companies list so that, if a new Company that hasn't been previously persisted is in the list, it would be automatically persisted together with the User:

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,因为它试图使用相同的主键保持(插入)新公司:

By setting cascadeType.PERSIST on the @ManyToMany, this works just fine. But if the list of companies contains a Company that was previsouly persisted, I get a MySQLIntegrityConstraintViolationException, since it's trying to persist (INSERT) a new Company with the same primary key:

User newUser = new User();

Company oldCompany = companyDAO.find(oldCompanyId);
List<Company> companies = new ArrayList<Company>();
companies.add(oldCompany);

newUser.setCompanies(companies);

entityManager.persist(newUser);

那么应如何设置以便新公司自动保留,但现有公司只需添加用户公司映射?

So how should this be set up so that new Companies are automatically persisted, but existing Companies are simply added to the user-company mapping?

推荐答案

在hibernate中考虑级联的最佳方法是调用方法X然后它将在每个子节点上调用方法X.所以,是的,如果你对用户进行持久调用,那么无论是否持续存在,它都会对每个孩子进行持久调用。

The best way to think about cascades in hibernate is if you call the method X on the parent then it will call the method X on each of the children. So yes, if you call persist on the user then it will call persist on each of the children, regardless of whether they have been persisted or not.

这种情况不是理想情况下用级联处理。级联持久性适用于所有子项都是使用父级创建的情况(例如,如果用户具有技能列表),则更多用于一对多。

This situation is not ideally handled with cascades. Cascade persist is intended for situations where all children are created with the parent (for example, if a use had a list of "skills") and more intended for one-to-many.

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

I would personally not use a cascade in this situation. Flagrant use of cascades when they are not needed can slow an application down.

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

If you feel you must use a cascade you can use a cascade merge. Merge will persist entities when they are not persisted already. However, merge has some very bizarre side effects which is probably why you didn't notice it working. Consider the following example:

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

这篇关于如何级联只保留新实体的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆