在以前使用hibernate时,经常对保存存在关联关系的对象时,不确定是否能保存成功。
因此,特意对一对多关系的2个对象进行实践。
一、pojo类和配置文件的准备
这里有一点提前说一下,
外键列在数据库中
并没有设置为不为null。因此可以出现外键为空的情况。
(1)pojo类
![1222688-20170819183831365-1979593439.png](https://i-blog.csdnimg.cn/blog_migrate/ebc530e2f239b794f5552c68e6100e77.png)
![1222688-20170819183831787-1854680734.png](https://i-blog.csdnimg.cn/blog_migrate/9810454d6bc4cb551cb8857951abaae7.png)
(2)映射文件
![1222688-20170819183832896-1592247202.png](https://i-blog.csdnimg.cn/blog_migrate/2ac2b57c4f3725c96e676e882de005e0.png)
![1222688-20170819183833787-588410349.png](https://i-blog.csdnimg.cn/blog_migrate/1f99d89ee596f7b481a48865995d4495.png)
(3)测试类中方法的准备
![1222688-20170819183834662-286262082.png](https://i-blog.csdnimg.cn/blog_migrate/6dc6e5034acb91a88b09ee6efffebe16.png)
二、双方都维护关联关系且双向关联
注意:这里的双向关联是指双向都建立关系
(1)1方和多方都保存,且建立了双向关联的关系。这样是肯定可以
保存成功的。
![1222688-20170819183835287-360414271.png](https://i-blog.csdnimg.cn/blog_migrate/903a4ae8053e0c5da8e701d3db696641.png)
![1222688-20170819183836006-517867361.png](https://i-blog.csdnimg.cn/blog_migrate/3f30fe32cef6e61b992299515bc70029.png)
(2)1方或多方中,有一方没有保存。那么会
保存失败,因为保存时分类是瞬时态对象,所以失败。
![1222688-20170819183836678-1046829890.png](https://i-blog.csdnimg.cn/blog_migrate/f9f316b3a3ecccb8de120574ca6b74ab.png)
![1222688-20170819183837490-60648165.png](https://i-blog.csdnimg.cn/blog_migrate/b3fba18dfb639dcb6371e1e4ccf12db7.png)
(3)在(2)的代码的基础上,给product的映射文件中配置一个级联保存。这样在保存产品时就会级联保存分类,这样
分类就
不是瞬时态对象了,
保存成功!
![1222688-20170819183838068-1751536169.png](https://i-blog.csdnimg.cn/blog_migrate/62c6026bf0e9c170734152ccebc99933.png)
![1222688-20170819183838568-19638028.png](https://i-blog.csdnimg.cn/blog_migrate/f37c142bb068cc7c263158a86787d028.png)
三、双向维护外键,但只建立单向关联关系
(1)产品中没有分类,由于外键可以为null;因此可以
保存成功。
![1222688-20170819183839225-44852186.png](https://i-blog.csdnimg.cn/blog_migrate/7ec7f422a80a2ee41674fe5a85bc8171.png)
![1222688-20170819183839693-1732965823.png](https://i-blog.csdnimg.cn/blog_migrate/94c94e0118d72b95c6b5f0765e504353.png)
(2)产品中没有分类,分类中有产品。产品和分类都执行保存,保存成功。
![1222688-20170819183840412-1212003128.png](https://i-blog.csdnimg.cn/blog_migrate/10a5d46e4b9d4ba90f805bacfdba9a20.png)
![1222688-20170819183840975-1377628370.png](https://i-blog.csdnimg.cn/blog_migrate/750d77ffde98100aa3e3e021078aff84.png)
(3)产品中没有分类,分类中有产品,只保存分类。这里肯定保存失败,因为分类也会维护外键。
当分类维护外键时,发现集合里面的产品是瞬时态对象。所以肯定
保存失败了。
![1222688-20170819183841818-2047787659.png](https://i-blog.csdnimg.cn/blog_migrate/c2ac76c7fc92a350eff2536784e17104.png)
四、外键只靠多方维护
先把一方维护外键的功能取消,只需要在分类的映射文件中,配置inverse为true
![1222688-20170819183842303-1121103530.png](https://i-blog.csdnimg.cn/blog_migrate/f0205e65af6de58c036a35fac1436731.png)
(1)产品中有分类,只保存产品。这样由于保存产品时,会去维护外键,而用来维护外键的分类对象为瞬时态对象,所以一定
保存失败。
![1222688-20170819183843428-1178692908.png](https://i-blog.csdnimg.cn/blog_migrate/dfe4229179f4c9bce1fcaeec8e66fa0b.png)
(2)针对(1)我们在保存产品后面添加保存分类。这样保存产品时,用于维护外键用的对象就是持久态对象了。这样就
保存成功了。
![1222688-20170819183844615-1969193890.png](https://i-blog.csdnimg.cn/blog_migrate/5f9af75a0a2ad7083e88ef0ea95cbba7.png)
(3)产品中有分类,分类中有产品,只保存分类。
保存成功。因为分类不会维护外键,所以不管集合里面装什么状态的对象都不影响。
![1222688-20170819183846271-1047966291.png](https://i-blog.csdnimg.cn/blog_migrate/a9522fd5ecc8eca8a96a76e64b7427e3.png)
(4)产品中有分类,只保存分类。一定
保存成功,因为分类不维护外键,且用于维护外键的对象也没有。道理同(3)。
![1222688-20170819183847365-391899951.png](https://i-blog.csdnimg.cn/blog_migrate/5287db9352fff6b95831c835a4472daf.png)
五、总结
看了这么多实例,发现保存失败的原因都是一样的。就是拿来去更新外键的对象(这个描述可能有点绕口)不能是瞬时态。
比如,产品这一方维护外键的话,那么他的用来更新外键的对象就是他里面的那个分类。如果这个分类是瞬时态对象,肯定保存失败。