Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/353.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 冬眠——”;已分离的实体传递给persist“;已持久化子级的错误_Java_Hibernate_Jpa_Orm_Persistence - Fatal编程技术网

Java 冬眠——”;已分离的实体传递给persist“;已持久化子级的错误

Java 冬眠——”;已分离的实体传递给persist“;已持久化子级的错误,java,hibernate,jpa,orm,persistence,Java,Hibernate,Jpa,Orm,Persistence,我有一个实体,它已经被持久化,并希望将其添加到新生成的父实体(尚未持久化)。如果我尝试持久化父对象,那么会出现错误“分离的实体传递给persist:model.Child”。我想我必须为孩子调用“entityManager.merge()”而不是“entityManager.persist()”。但我没有明确地称之为persist。这由“cascade=CascadeType.ALL”注释处理。如果实体已经存在,我可以告诉hibernate在这里进行合并吗 顺便说一下:如果我先持久化父对象,然后

我有一个实体,它已经被持久化,并希望将其添加到新生成的父实体(尚未持久化)。如果我尝试持久化父对象,那么会出现错误“分离的实体传递给persist:model.Child”。我想我必须为孩子调用“entityManager.merge()”而不是“entityManager.persist()”。但我没有明确地称之为persist。这由“cascade=CascadeType.ALL”注释处理。如果实体已经存在,我可以告诉hibernate在这里进行合并吗

顺便说一下:如果我先持久化父对象,然后添加子对象,然后再次持久化父对象->它可以工作(但会使我的应用程序逻辑更加复杂)

这是我的代码:

public class App 
{
    @Test
    public void test()
    {

        // I have a child object (in the real app 
        //this is a user object and already persisted
        Child child = new Child();
        HibernateHelper.persist(child);

        Parent parent = new Parent();

        parent.addChildren(child);
        // throws the exception "detached entity passed to persist: model.Child"
        HibernateHelper.persist(parent);

        Parent newParent = HibernateHelper.find(Parent.class, parent.getId());
        assertEquals(1,  newParent.getChildren().size());

    }
}
我的“孩子”实体:

我的“母公司”实体:


一个选项是始终使用EntityManager.merge。如果传递了一个新实体,它将被持久化;如果传递了一个分离的实体,它将被合并到当前持久化上下文中。

这种方法有什么缺点吗?merge返回一个托管实例,persist将参数转换为托管实例。调用persist方法后对对象的进一步更改将不会反映到数据库中,但在调用merge时,您的当前实现中已经有了这些更改
@Entity
@Table(name = "child")
public class Child {

    public Child(){}

    private Long id;

    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    private Parent parent;

    @ManyToOne
    @JoinColumn
    public Parent getParent() {
        return parent;
    }

    public void setParent(Parent parent) {
        this.parent = parent;
    }



}
@Entity
@Table(name="parent")
public class Parent {

    public Parent(){}

    private Long id;

    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    private Set<Child> children = new HashSet<Child>();

    @OneToMany(mappedBy = "parent", cascade = CascadeType.ALL)
    public Set<Child> getChildren() {
        return children;
    }
    public void setChildren(Set<Child> children) {
        this.children = children;
    }
    public void addChildren(Child child){
        children.add(child);
        child.setParent(this);
    }
}
public static void persist(Parent entity){

    EntityManager entityManager = null;
    try {
        entityManager = beginTransaction();

        if(entity.getId()!=null){
            entityManager.merge(entity);
        }else{
            entityManager.persist(entity);
        }
        entityManager.getTransaction().commit();
    } catch (Exception e) {
        System.out.println(e);
        return;
    }finally{
        if(entityManager != null)
            entityManager.close();
    }
}