zoukankan      html  css  js  c++  java
  • hibernate级联删除问题

    有用户和用户组两个表,需要使用hibernate做级联删除。映射文件如下:

    Groups.hbm.xml

    <class name="com.cms.entity.Groups" table="groups" catalog="cms">
            <id name="id" type="java.lang.Integer">
                <column name="id" />
                <generator class="native"></generator>
            </id>
            <property name="name" type="java.lang.String">
                <column name="name" length="100" not-null="true" />
            </property>
            <property name="description" type="java.lang.String">
                <column name="description" length="500" />
            </property>
            <property name="authority" type="java.lang.String">
                <column name="authority" length="200" />
            </property>
    
            <set name="users" inverse="true" lazy="false" cascade="all-delete-orphan">
                <key>
                    <column name="group_id" not-null="true" />
                </key>
                <one-to-many class="com.cms.entity.User" />
            </set>
    </class>

    User.hbm.xml

    <hibernate-mapping>
        <class name="com.cms.entity.User" table="user" catalog="cms">
            <id name="id" type="java.lang.Integer">
                <column name="id" />
                <generator class="native"></generator>
            </id>
            <many-to-one name="groups" class="com.cms.entity.Groups" fetch="select">
                <column name="group_id" not-null="true" />
            </many-to-one>
            <property name="name" type="java.lang.String">
                <column name="name" length="50" not-null="true" />
            </property>
            <property name="password" type="java.lang.String">
                <column name="password" length="200" not-null="true" />
            </property>
            <property name="qq" type="java.lang.String">
                <column name="qq" length="50" />
            </property>
            <property name="phone" type="java.lang.String">
                <column name="phone" length="50" />
            </property>
            <property name="postDate" type="java.util.Date">
                <column name="post_date" length="0" not-null="true" />
            </property>
            <set name="articles" inverse="true" cascade="all-delete-orphan">
                <key>
                    <column name="user_id" not-null="true" />
                </key>
                <one-to-many class="com.cms.entity.Article" />
            </set>
        </class>
    </hibernate-mapping>

    原本要做的是,删除用户组时将其下所属的用户全部删除;删除用户时,不对用户组进行更改。

    结果过执行报错:deleted object would be re-saved by cascade (removedeleted object from associations)

    感觉可能是cascade的配置问题,修改了下发现还是报错。后来我将Groups映射文件中<set>元素的lazy属性设置为true。删除成功!但是这样由于是延迟加载,就没法在页面中通过groups来获取User集合中的对象了(本来是想统计用户组中用户成员的个数)。于是还得修改。

    查了文档弄明白了怎么回事。

    原来cascade属性在lazy=true的时候不起作用(集合中对象还没初始化)。所以在删除User的时候,就不会触发对关联关系的维护。

    而当lazy=false的时候,由于我们设置了cascade,那么删除User的时候会触发关系维护,此时虽然在user中已经将对应的Groups属性设置为null(删除前会先将外键设置为null)。但是由于Groups中的Set中仍然还保持着我们删除的User对象,所以触发关系维护的时候,这个User对象又会被重新保存到数据库中。造成了前面出现的异常。

    当然,如果我们删除Groups的时候,如果没有将Set的cascade设置为all或delete,那么就会报错: Cannot delete or update a parent row:a foreign key constraint fails,因为groups删除了,User中对groups的外键引用怎么办?

    解决的办法就是,如果不需要在groups中直接获取Set中的User对象,那么就把lazy设置为true就可以了。不设置cascade也可以,不过删除groups的时候就可能有问题了。或者通过代码,在删除之前将关联关系解除。

    public void delete(User entity) {          
    
                   entity.getGroups().getUsers().remove(entity);
                   entity.setGroups(null);
    
                   userDao.delete(entity);
    
     }



  • 相关阅读:
    iptables命令参数简介
    在linux下开启IP转发的方法
    Linux配置IP路由
    NAT转换
    JS实验案例
    Ubuntu kylin优麒麟root用户与静态网络设置
    非对称加密-RSA
    对称加密-DES
    DM5详解
    Visio的安装教程
  • 原文地址:https://www.cnblogs.com/jdluojing/p/3212415.html
Copyright © 2011-2022 走看看