inverse和cascade的区别,以及一对多添加操作时外键为Null的问题

时间:2022-10-09 03:37:24

inverse和cascade的区别

问题:在我们做一对多添加操作时,如果设置了inverse=true。同时设置了cascade=”save-update,delete”时,那么添加数据时Hibernate并不会帮我们设置多的那一方的外键关联。也就是说多的那一方外键将为null。(这里说的是一对多的关系)

演示问题:
这是配置代码:

<set name="linkMans" cascade="save-update" inverse="true">
        <key column="clid"></key>
        <one-to-many class="cn.domarvel.entity.LinkMan"/>
</set>

Java代码:

    @Test
    public void showCreate02(){
        Transaction transaction=null;
        try {
            Session session=HibernateUtils.getCurrentSession();
            transaction=session.beginTransaction();

            Customer customer=new Customer(null, "锤子科技", "svip", "网络", "110", "120");
            LinkMan linkMan=new LinkMan("锤老板", "男", "456");

            customer.getLinkMans().add(linkMan);
            session.save(customer);

            transaction.commit();
        } catch (Exception e) {
            e.printStackTrace();
            transaction.rollback();
        }
    }

输出结果:

Hibernate: 
    insert into customer (custName, custLevel, custSource, custPhone, custMobile) values (?, ?, ?, ?, ?) Hibernate: insert into linkman (lname, lgender, lphone, clid) values (?, ?, ?, ?) //这个时候只会看见两个插入语句

在来看看表中的变化:

inverse和cascade的区别,以及一对多添加操作时外键为Null的问题

很明显这里出现了问题。

  • 那么为什么会出现这个问题呢??因为cascade=”save-update”的意思是在更新或者保存的时候帮我们设置对象与对象的关系。(比如上面的代码,我们并没有对多的那方进行session.save操作,但是还是能够成功插入多的那方的数据,这就是cascade=”save-update”的功能)。
  • inverse=”false”(inverse的默认值为false)的意思是帮我们维护多的那方的外键关系。

也就是说如果这样写,就能够既能够成功保存数据,也能够成功设置外键关系:

        <set name="linkMans" cascade="save-update" inverse="false">
            <key column="clid"></key>
            <one-to-many class="cn.domarvel.entity.LinkMan"/>
        </set>

但是,对于更新表关系操作时,我们就必须把inverse的值修改为true。这就有点互相矛盾了。

所以当我们既要做更新表关系时不影响性能,也要同时在添加操作时能够设置好外键关系:

解决方案就是:我们自己来维护表的外键关系。

配置代码:

        <set name="linkMans" cascade="save-update" inverse="true">
            <key column="clid"></key>
            <one-to-many class="cn.domarvel.entity.LinkMan"/>
        </set>

Java最终添加的代码:

    @Test
    public void showCreate02(){
        Transaction transaction=null;
        try {
            Session session=HibernateUtils.getCurrentSession();
            transaction=session.beginTransaction();

            Customer customer=new Customer(null, "爱智科技", "svip", "网络", "110", "120");
            LinkMan linkMan=new LinkMan("狼仔", "男", "456");

            customer.getLinkMans().add(linkMan);
            linkMan.setCustomer(customer);
            session.save(customer);

            transaction.commit();
        } catch (Exception e) {
            e.printStackTrace();
            transaction.rollback();
        }
    }