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 (?, ?, ?, ?) //这个时候只会看见两个插入语句
在来看看表中的变化:
很明显这里出现了问题。
- 那么为什么会出现这个问题呢??因为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();
}
}