在Hibernate中,删除存在关联关系的一个对象时,会出现 org.hibernate.ObjectDeletedException: deleted object would be re-saved by cascade (remove deleted object from associations)这个异常
如下:
持久化类:
import java.util.HashSet;
import java.util.Set;
import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.commons.lang.builder.HashCodeBuilder;
import org.apache.commons.lang.builder.ToStringBuilder;
/**
* 产品类别对象
* @author crazycy
*
*/
public class ProductCategory extends BaseObject {
// Fields
private long id;
private String name;
private String description;
private ProductCategory parentCategory;
private Set childrenCategories = new HashSet();
// Constructors
/** default constructor */
public ProductCategory() {
}
/** minimal constructor */
public ProductCategory(String name) {
this.name = name;
}
public ProductCategory(String name, String description) {
this.name = name;
this.description = description;
}
/** full constructor */
public ProductCategory(String name, String description,
ProductCategory parentCategory) {
this.name = name;
this.description = description;
this.parentCategory = parentCategory;
}
/** full constructor */
public ProductCategory(String name, String description,
Set childrenCategories) {
this.name = name;
this.description = description;
this.childrenCategories = childrenCategories;
}
// Property accessors
public long getId() {
return this.id;
}
public void setId(long id) {
this.id = id;
}
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
public String getDescription() {
return this.description;
}
public void setDescription(String description) {
this.description = description;
}
public ProductCategory getParentCategory() {
return this.parentCategory;
}
public void setParentCategory(ProductCategory parentCategory) {
this.parentCategory = parentCategory;
}
/**
* 由主来调:是主添加
* @param productCategory
*/
public void addCategory(ProductCategory productCategory) {
productCategory.setParentCategory(this);
childrenCategories.add(productCategory);
}
/**
* 由主来调;是从主删除
* @param productCategory
*/
public void removeCategory(ProductCategory productCategory) {
childrenCategories.remove(productCategory);
productCategory.setParentCategory(null);
}
public Set getChildrenCategories() {
return childrenCategories;
}
public void setChildrenCategories(Set childrenCategories) {
this.childrenCategories = childrenCategories;
}
/**
* @see java.lang.Object#equals(Object)
*/
public boolean equals(Object object) {
if (!(object instanceof ProductCategory)) {
return false;
}
ProductCategory rhs = (ProductCategory) object;
return new EqualsBuilder().append(this.description, rhs.description)
.append(this.name, rhs.name).append(this.id, rhs.id).isEquals();
}
/**
* @see java.lang.Object#hashCode()
*/
public int hashCode() {
return new HashCodeBuilder(1009592109, -669108101).append(
this.description).append(this.name).append(this.id)
.toHashCode();
}
/**
* @see java.lang.Object#toString()
*/
public String toString() {
return new ToStringBuilder(this).append("name", this.name).append(
"description", this.description).append("id", this.id)
.toString();
}
}
映射文件
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="">
<class name="ProductCategory" table="productcategory">
<id name="id" type="long">
<column name="ID" />
<generator class="native" />
</id>
<property name="name" type="string">
<column name="name" length="50" not-null="true" />
</property>
<property name="description" type="string">
<column name="description" length="150" />
</property>
<set name="childrenCategories" cascade="save-update" inverse="true">
<key column="parent"/>
<one-to-many class="ProductCategory"/>
</set>
<many-to-one name="parentCategory" column="parent"
class="ProductCategory"
cascade="save-update"
>
</many-to-one>
</class>
</hibernate-mapping>
测试代码:
category2.getChildrenCategories().remove(category5);
category5.setParentCategory(null);
dao.removeProductCategory(category5.getId());
解决方案如下:
方法1 删除Set方的cascade
方法2 解决关联关系后,再删除 :
category2.getChildrenCategories().remove(category5);
category5.setParentCategory(null);
dao.removeProductCategory(category5.getId());
方法3 在many-to-one方增加cascade 但值不能是none
如果以上三个方案都失败(哼哼~ 我用了5个小时才找出来的)
检查一下hashCode equals是否使用了id作为唯一标示的选项了;我用uuid.hex时是没有问题的;
但是用了native,就不行了,怎么办?删除啊!
也就是问题出现在本文给出的持久化类的hashCode equals方法身上