org.hibernate.NonUniqueObjectException报错后,从配置文件中的hibernate-inverse与cascade 得到解决问题

今天,在写代码的时候多复制了行代码,即重复对SET对象添加了两次相同的对象,由于调用保存的方法不是自己写的,其中代码只用了一句session.save(object),就保存了关联的SET对象,但Hibernate配置文件中该对象的配置为:inverse="true" cascade="save-update",以前我并没有这样写法,感觉很奇异,为什么invserse="true",关系的维护端不是在多的那一端进行维护吗,但对cascade="save-update",感觉是这个起到保存时级联保存了SET集合中的对象,在网上找到了一篇文章,使得疑惑得到了较好的解决!

 

下面以部门(Department)和员工(Employee)为例说明“维护关系”和“级联操作”。

1 inverse

class Department{
private int id;
private String name;
private Set<Employee> emps;
//getter and setter.......
}

class Employee{
private int id;
private String name;
private Department depart;
//getter and setter.......
}


维护关系在对象模型上就是将关联的domain对象的对象属性set进去比如
Employee emp=new Employee();
emp.setName("programmer")
Department depart=new Department();
depart.setName("software")
emp.setDepart(depart);//对象模型上建立关系,使emp对象保有完整关系信息
Set<Employee> emps=new HashSet<Employee>();
emps.add(emp);
depart.setEmps(emps);//对象模型上建立关系,使depart对象保有完整关系信息

数据库模型上关系维护靠外键,建立关系的方法只有把“多”的一方的表的外键字段更新为主表的主键
在对象模型上,两端的对象都可以通过set方法建立完整的关联关系;而在关系模型上,只有从表才能通过设定外键的方式维护关系
hibernate在讲对象间的关联关系转化为数据库表间的关联关系的时候,inverse属性就派上用场了。
inverse属性只能设定在一对多映射“一”这端的部分集合,通常是set上,值为true表示“一”(Department)端放弃对维护关联关系,即对“一”端表的save操作不会导致“多”(Employee)端外键的更新,即使"一"端在对象上保有完整的关系信息;
值为false,表示维护关联关系,“一”端save后会主动更新“多端”的外键,维护关系;缺省为false。
值得说明的是,只有在“一” 这端(包含set这端)才有inverse属性设置,也是说只有“一”端能放弃维护关联关系,“多的那段永远维护”,如下代码:

session.save(emp);
总是维护关联关系。

2 cascade

cascade用来说明当对主对象之行动作时,是否也对从对象执行相同的动作。常用的动作有all,none,save-update
在上面大段代码后如果执行
session.save(depart),如果Department映射文件没有将 one-to-many的cascade属性设为“save-update”,程序会抛出异常,因为emp还没有保存;相反的,如果设置了cascade为“save-update”,则在保存depart的时候,emp也会级联保存,就不会有异常了。

3 inverse=true cascade=save-update

我推测这种设置在只session.save(depart)保存“一”(Department)端时,“多”端也会保存,但是外键没有更新。但是实验结果表明,外键还是更新了,即关系还是维护了。。为什么呢?原因是emp其实也保存了完整的关联关系,虽然save(depart)不维护关系了,但时save(depart)时的级联操作会保存emp,后者把关系维护进了关系表中。当不告诉emp完成的关系时(不给emp的depart属性set值),关系就彻底丢失了。

总结下,inverse用来设置将关系维护进关系表的规则,只维护和关系有关的字段;cascade用来定义规则,存储实体信息;两者没有直接关系。

最近有曹操读了一下java persistence with hibernate,看到了书中有关inverse和cascade的描述:

What is the relationship between cascade and inverse?

There is no relationship;both are different notions. The noninverse end of an association
is used to generate the SQL statements that manage the association in the
database (insertion and update of the foreign key column(s)). Cascading
enables transitive object state changes across entity class associations.

意思更加明了了

 

转载自:http://hi.baidu.com/wbafht/blog/item/d270d3ede219f4db2e2e21ed.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值