Hibernate之deleted object would be re-saved by cascade异常
在Hibernate中,删除存在关联关系的一个对象时,会出现 org.hibernate.ObjectDeletedException: deleted object would be re-saved by cascade (remove deleted object from associations)这个异常
如下:
持久化类:
映射文件
测试代码:
解决方案如下:
方法1 删除Set方的cascade
方法2 解决关联关系后,再删除 :
如果以上三个方案都失败(哼哼~ 我用了5个小时才找出来的)
检查一下hashCode equals是否使用了id作为唯一标示的选项了;我用uuid.hex时是没有问题的;
但是用了native,就不行了,怎么办?删除啊!
也就是问题出现在本文给出的持久化类的hashCode equals方法身上
如下:
持久化类:
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();
}
}
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 >
<! 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());
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
category5.setParentCategory( null );
dao.removeProductCategory(category5.getId());
如果以上三个方案都失败(哼哼~ 我用了5个小时才找出来的)
检查一下hashCode equals是否使用了id作为唯一标示的选项了;我用uuid.hex时是没有问题的;
但是用了native,就不行了,怎么办?删除啊!
也就是问题出现在本文给出的持久化类的hashCode equals方法身上