hibernate jpa manyToOne级联操作时,update时报出identifier of an instance of 问题的解决方案及update问题

来源:互联网 发布:淘宝联盟规则 编辑:程序博客网 时间:2024/05/29 17:47

   最近一直在用Jpa来做项目,jpa的优点这里我就不多说了,说一下最近使用时解决的一个问题吧。

首先来说,使用jpa进行update操作时,由于调用的是jpa封装好的save方法,所以如果表单页面中没有提到的参数,这时保存的时候,没有提到的参数就会被置为null,为此我想到的第一种解决方案就是把查询出来的数据写到页面表单的隐藏域中,可是这样以来,一些需要保密的数据就外泄了,感觉不合理,又想了超级麻烦的办法可以upate之前先查出原来的数据然后没有改变的再一一set进去,博主是年轻的赖人,这种方法不头疼呢!!!今天看了看原先框架里以前大神们写的代码,原来是这样处理:

使用的是spring mvc 的@ModelAttribute的特性,@ModelAttribute具体的特性可以参考这位大神写的@ModelAttribute特性。@ModelAttribute 会在你请求的方法前去使用





在这里使用了@ModelAttribute去查询了一下member信息,这样member中没有在表单中的数据就加载出来了


因为都是member对象,所以利用了@ModelAttribute的特性,如果提交的request中的参数中,有就set进去到member对象中,没有就不会set,这样member对象原来的参数就不会丢失,更改的参数也会保存进去,再调用jpa的save方法就没有问题了。

好了接下来解决manyToOne级联update的问题:


这里我的member对象与user对象是一个manyToOne的关系,如果在表单中更改这个one对象时会出现

这个问题是因为什么呢?我深入的研究了一下,原来是这样:

当我查询出这个member对象时,会连带着也查询出user对象

这里观察下user对象的hash值与id

当我在表单页面更改这个User对象时,查看提交上来的member对象时会发现:user的引用没有改变,只是我更改的id变化了,于是就会报出identifier of an instance of  34 to 31的问题,这个根本原因就是因为load缓存的问题,因为表单form只是改变了id值,但是Jpa保存的时候还是用的原来的user对象引用,所以就会出问题,其实解决这个问题也是十分简单的,只要重新一个user对象就可以,在这里也是十分巧妙的解决这个问题,就是在@ModelAttribute的方法中将member对象中的user属性置为null,这样就解决了问题


这个问题困扰了好几天,查网上的资料解决的都不是很清晰,这里分享出来。


0 0