您的位置:首页 > 移动开发 > Objective-C

org.hibernate.ObjectDeletedException: deleted instance passed to merge: [xxx#<null>]

2016-05-13 11:28 776 查看
今天在工作中碰到了这个错误,分析一番发现是代码中的有一段逻辑出现了问题:具体是在List中有若干对象,当遍历时删除了其中的一个对象,而后的语句中竟然还要保存这个对象。有点混乱是吧!!总之是保存了一个已经删除的对象。

下面是转载的有一点相似的地方:

转载自:http://blog.csdn.net/lichao3459/article/details/9225235
我们在使用hibernate或JPA的一对多、多对一进行删除操作的时候常会出现org.hibernate.ObjectDeletedException: deleted entity passed to  persist: [xxx#<null>]的错误。

 例如:建立deparment(部门)、user(人员)两个实体类:

[java] view
plaincopy

package com.yg.bean.user;  

  

import java.util.HashSet;  

import java.util.Set;  

  

import javax.persistence.Column;  

import javax.persistence.Entity;  

import javax.persistence.FetchType;  

import javax.persistence.Id;  

import javax.persistence.OneToMany;  

  

/** 

 * 部门信息实体类 

 * @author: LiChao 

 * date: Nov 6, 2012 -- 3:03:39 PM 

 */  

@Entity  

public class Department {  

  

    /*部门编号*/  

    private String code;  

    /*部门名称*/  

    private String name;  

    /*部门内员工*/  

    private Set<User> users = new HashSet<User>();  

  

    public Department() {}  

    public Department(String code) {  

        this.code = code;  

    }  

    public Department(String code, String name) {  

        this.code = code;  

        this.name = name;  

    }  

  

    @Id @Column(length=12,nullable=false)  

    public String getCode() {  

        return code;  

    }  

    public void setCode(String code) {  

        this.code = code;  

    }  

  

    @Column(length=60,nullable=false)  

    public String getName() {  

        return name;  

    }  

    public void setName(String name) {  

        this.name = name;  

    }  

  

    @OneToMany(mappedBy="dwdm",fetch=FetchType.EAGER)  

    public Set<User> getUsers() {  

        return users;  

    }  

    public void setUsers(Set<User> users) {  

        this.users = users;  

    }  

  

    @Override  

    public int hashCode() {  

        final int prime = 31;  

        int result = 1;  

        result = prime * result + ((code == null) ? 0 : code.hashCode());  

        return result;  

    }  

    @Override  

    public boolean equals(Object obj) {  

        if (this == obj)  

            return true;  

        if (obj == null)  

            return false;  

        if (getClass() != obj.getClass())  

            return false;  

        final Department other = (Department) obj;  

        if (code == null) {  

            if (other.code != null)  

                return false;  

        } else if (!code.equals(other.code))  

            return false;  

        return true;  

    }  

      

}  

[java] view
plain copy

<span style="font-size:14px;">package com.yg.bean.user;  

  

import java.util.HashSet;  

import java.util.Set;  

  

import javax.persistence.Column;  

import javax.persistence.Entity;  

import javax.persistence.FetchType;  

import javax.persistence.Id;  

import javax.persistence.OneToMany;  

  

/** 

 * 部门信息实体类 

 * @author: LiChao 

 * date: Nov 6, 2012 -- 3:03:39 PM 

 */  

@Entity  

public class Department {  

  

    /*部门编号*/  

    private String code;  

    /*部门名称*/  

    private String name;  

    /*部门内员工*/  

    private Set<User> users = new HashSet<User>();  

  

    public Department() {}  

    public Department(String code) {  

        this.code = code;  

    }  

    public Department(String code, String name) {  

        this.code = code;  

        this.name = name;  

    }  

  

    @Id @Column(length=12,nullable=false)  

    public String getCode() {  

        return code;  

    }  

    public void setCode(String code) {  

        this.code = code;  

    }  

  

    @Column(length=60,nullable=false)  

    public String getName() {  

        return name;  

    }  

    public void setName(String name) {  

        this.name = name;  

    }  

  

    @OneToMany(mappedBy="dwdm",fetch=FetchType.EAGER)  

    public Set<User> getUsers() {  

        return users;  

    }  

    public void setUsers(Set<User> users) {  

        this.users = users;  

    }  

  

    @Override  

    public int hashCode() {  

        final int prime = 31;  

        int result = 1;  

        result = prime * result + ((code == null) ? 0 : code.hashCode());  

        return result;  

    }  

    @Override  

    public boolean equals(Object obj) {  

        if (this == obj)  

            return true;  

        if (obj == null)  

            return false;  

        if (getClass() != obj.getClass())  

            return false;  

        final Department other = (Department) obj;  

        if (code == null) {  

            if (other.code != null)  

                return false;  

        } else if (!code.equals(other.code))  

            return false;  

        return true;  

    }  

      

}  

</span>  

[java] view
plaincopy

package com.yg.bean.user;  

  

import javax.persistence.CascadeType;  

import javax.persistence.Column;  

import javax.persistence.Id;  

import javax.persistence.JoinColumn;  

import javax.persistence.ManyToOne;  

  

import org.hibernate.annotations.NotFound;  

import org.hibernate.annotations.NotFoundAction;  

  

/** 

 * 系统用户信息实体类 

 * @author: LiChao 

 * date: Nov 6, 2012 -- 3:45:02 PM 

 */  

public class User1 {  

    /*id*/  

    private String id;  

    /*用户名*/  

    private String name;  

    /**/  

    private Integer age;  

    /*部门*/  

    private Department dep;  

      

    @Id @Column(length=6,nullable=false)  

    public String getId() {  

        return id;  

    }  

    public void setId(String id) {  

        this.id = id;  

    }  

    @Column(length=30,nullable=true)  

    public String getName() {  

        return name;  

    }  

    public void setName(String name) {  

        this.name = name;  

    }  

    @Column(nullable=true)  

    public Integer getAge() {  

        return age;  

    }  

    public void setAge(Integer age) {  

        this.age = age;  

    }  

    @ManyToOne(cascade=CascadeType.REFRESH)  

    @JoinColumn(name="dep")  

    @NotFound(action=NotFoundAction.IGNORE)  

    public Department getDep() {  

        return dep;  

    }  

    public void setDep(Department dep) {  

        this.dep = dep;  

    }  

}  

[java] view
plain copy

<span style="font-size:14px;">package com.yg.bean.user;  

  

import javax.persistence.CascadeType;  

import javax.persistence.Column;  

import javax.persistence.Id;  

import javax.persistence.JoinColumn;  

import javax.persistence.ManyToOne;  

  

import org.hibernate.annotations.NotFound;  

import org.hibernate.annotations.NotFoundAction;  

  

/** 

 * 系统用户信息实体类 

 * @author: LiChao 

 * date: Nov 6, 2012 -- 3:45:02 PM 

 */  

public class User1 {  

    /*id*/  

    private String id;  

    /*用户名*/  

    private String name;  

    /**/  

    private Integer age;  

    /*部门*/  

    private Department dep;  

      

    @Id @Column(length=6,nullable=false)  

    public String getId() {  

        return id;  

    }  

    public void setId(String id) {  

        this.id = id;  

    }  

    @Column(length=30,nullable=true)  

    public String getName() {  

        return name;  

    }  

    public void setName(String name) {  

        this.name = name;  

    }  

    @Column(nullable=true)  

    public Integer getAge() {  

        return age;  

    }  

    public void setAge(Integer age) {  

        this.age = age;  

    }  

    @ManyToOne(cascade=CascadeType.REFRESH)  

cc31
    @JoinColumn(name="dep")  

    @NotFound(action=NotFoundAction.IGNORE)  

    public Department getDep() {  

        return dep;  

    }  

    public void setDep(Department dep) {  

        this.dep = dep;  

    }  

}  

</span>  

      当我们在删除user表中的记录的时候就会报我们之前提到的异常,这是什么原因呢?细心的朋友可能注意到了,在depatment实体中department对user为一对多关系,并且加载方式为“立即加载”(fetch=FetchType.EAGER),关键就在这里,你可以简单理解为当你调用了department实体后,就会立即得到对表user的数据的引用,所以你再对user表中的数据经行删除的时候是不被允许的。解决方法我想到了两种:

1、最简单的方法:抓取策略改为懒加载方式(fetch=FetchType.LAZY)。但是这种方法在你调用department.getUsers();后再进行删除user表中记录的操作的时候仍会报相同异常,并且还极有可能报session已关闭异常。

2、比较完美的方法:department.getUsers().clear();为防止session已关闭异常,我们有时候必须将加载策略设为立即加载,怎么完美解决呢?很简单!在你删除user表中数据前先执行department.getUsers().clear();就可以了,你可以理解为:清除对user表数据的引用。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: