• hibernate CasCade deleted object ould be re-saved by cascade


    这个问题个人认为看你用的那种方式,如果是注解式的

    比如:

    @ManyToMany(cascade={CascadeType.MERGE,CascadeType.REFRESH,CascadeType.PERSIST}, fetch = FetchType.LAZY)

        @JoinTable(name = "F_USERTOAUTHORITY", joinColumns = { @JoinColumn(name = "authorityid") }, inverseJoinColumns = { @JoinColumn(name = "userid") })

        private List<User> users;

    CascadeType不要写成all就可以解决了!

    deleted object ould be re-saved by cascade

    在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方法身上

    hibernate注解的CascadeType属性

     

    cascade表示级联操作   


       CascadeType.MERGE级联更新:若items属性修改了那么order对象保存时同时修改items里的对象。对应EntityManager的merge方法 

      
       CascadeType.PERSIST级联刷新:获取order对象里也同时也重新获取最新的items时的对象。对应EntityManager的refresh(object)方法有效。即会重新查询数据库里的最新数据   
       

      CascadeType.REFRESH级联保存:对order对象保存时也对items里的对象也会保存。对应EntityManager的presist方法   
       

      CascadeType.REMOVE级联删除:对order对象删除也对items里的对象也会删除。对应EntityManager的remove方法   

    CascadeType.PERSIST只有A类新增时,会级联B对象新增。若B对象在数据库存(跟新)在则抛异常(让B变为持久态)

    CascadeType.MERGE指A类新增或者变化,会级联B对象(新增或者变化)

    CascadeType.REMOVE只有A类删除时,会级联删除B类;

    CascadeType.ALL包含所有;

    CascadeType.REFRESH没用过。

    综上:大多数情况用CascadeType.MERGE就能达到级联跟新又不报错,用CascadeType.ALL时要斟酌下CascadeType.REMOVE

    @Fetch:

    定义了加载关联关系的获取策略. FetchMode 可以是

    SELECT (在需要加载关联的时候触发select操作), SUBSELECT(只对集合有效,使用了子查询策略,详情参考Hibernate参考文档)

    JOIN (在加载主实体(owner entity)的时候使用SQL JOIN来加载关联关系).

    JOIN 将覆写任何延迟属性 (通过 JOIN策略加载的关联将不再具有延迟性).

  • 相关阅读:
    Online ddl 工具之pt-online-schema-change
    【MySql】mysql 慢日志查询工具之mysqldumpslow
    赶集网mysql开发36条军规
    MySQL数据库高并发优化配置
    mysql的表分区
    mysql 如果处理货币金钱类型
    bootstrab table+表格 select可编辑完整实例
    mongoDb 给表添加+ 删除字段
    mongoDb +Java+springboot
    java+数据库+D3.js 实时查询人物关系图
  • 原文地址:https://www.cnblogs.com/wangliansong/p/3277626.html
Copyright © 2020-2023  润新知