起因:

公司业务需求,增加了一个新的数据源,增加之后,起初一切正常,但是发现后台管理系统所有Ajax请求获取信息没有问题,但是涉及到保存操作就抛出异常。

异常:

org.hibernate.NonUniqueObjectException: a different object with the same identifier value was already associated with the session

思路:

在stackoverflow上查了很久,大概是说一个hibernate的session保存了两个Object,可以怎么想都想不通,因为我每个Action都只获得了Ajax发送过来的一个对象,哪里来的两个对象呢?又想是不是我两个数据源两个session导致的,最后排除了,最后仔细检查配置文件,在web.xml发现了疑似问题的所在:opensessioninviewFilter

背景:

首先说我之前为什么配置opensessioninviewFilter,在使用Hibernate中的one-to-many、many-to one、many-to-many关系映射的时候,一个对象中会包含一个或多个Set来关联其他的对象。例如:user-groups,当程序取user 对象时,如果一个用户有多个自定义组,那么程序将把组的信息也读取出来,在log中可以看到两个sql的输出。但是在页面的显示上,也许并不需要显示这个用户相关组的信息,这样系统的消耗就白白浪费了,当数据量比较大的时候这是相当消耗性能的,于是想到了hibernate提供的lazy(延迟加载)来避免这一情况的发生,然后再xml中设置lazy=true,实现了延迟加载,但是当hibernate+spring配合使用的时候,如果设置了lazy=true,那么在读取数据的时候,当读取了父数据后,hibernate会自动关闭session,这样,当要使用子数据的时候,系统会抛出lazyinit的错误,这时就需要使用spring提供的 OpenSessionInViewFilter,OpenSessionInViewFilter主要是保持Session状态知道request将全部页面发送到客户端,这样就可以解决延迟加载带来的问题OpenSessionInViewFilter的主要功能是用来把一个Hibernate Session和一次完整的请求过程对应的线程相绑定。目的是为了实现"Open Session in View"的模式。例如: 它允许在事务提交之后延迟加载显示所需要的对象。OpenSessionInViewFilter 过滤器将 Hibernate Session 绑定到请求线程中,它将自动被 Spring 的事务管理器探测到。所以 OpenSessionInViewFilter 适用于 Service 层使用HibernateTransactionManager 或 JtaTransactionManager 进行事务管理的环境,也可以用于非事务只读的数据操作中。web.xml中的配置要注意先后顺序,OpenSessionInViewFilter要在struts2的filter前面,(这个是为什么呢?)否则系统会报错。对于OpenSessionInView的配置中,singleSession应该设置为true(在哪儿设置呢?),表示一个request只能打开一个 session,如果设置为false的话,session可以被打开多个,这时在update、delete的时候会出现打开多个session的异常。

    <filter>
<filter-name>hibernateOpenSessionInViewFilter</filter-name>
<filter-class>org.springframework.orm.hibernate4.support.OpenSessionInViewFilter</filter-class>
<init-param>
<param-name>singleSession</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>hibernateOpenSessionInViewFilter</filter-name>
<servlet-name>SpringMVC</servlet-name>
<url-pattern>/</url-pattern>
</filter-mapping>

解决办法:

最后将opensessioninviewFilter的配置注释掉就一切正常了,如果配置了opensessioninviewFilter,将session提前关闭,让Session和一次完整的请求过程对应的线程相绑定,可以具体业务中有两个数据源,所以有两个session,当接收ajax的请求时,hibernate不知道线程对应的是哪个session,所以导致hibernate抛出异常,但是正如上面所说如果不用懒加载,则大大增加了服务器的压力,目前我还没有想到更好的解决办法,如果哪位大牛有好的办法的,希望能够予以指教。

opensessioninviewFilter导致org.hibernate.NonUniqueObjectException的更多相关文章

  1. org.hibernate.NonUniqueObjectException: a different object with the same identifier value was already associated with the session:

    保存实体异常 https://blog.csdn.net/zzzz3621/article/details/9776539 org.hibernate.NonUniqueObjectException ...

  2. 解决org.hibernate.NonUniqueObjectException的问题

    不知道是不是之前处理懒加载的问题对session工厂进行了处理,导致了之前没有问题的地方出现了错误. 当修改班级操作时出现了错误 前端错误信息 后台处理以及报错信息 16:37:36,034 ERRO ...

  3. org.hibernate.NonUniqueObjectException: a different object with the same identifier value was alread---------程序报错

    今天遇到了这个问题: org.hibernate.NonUniqueObjectException: a different object with the same identifier value ...

  4. hibernate异常:org.hibernate.NonUniqueObjectException

    异常:org.hibernate.NonUniqueObjectException 提示:a different object with the same identifier value was a ...

  5. org.hibernate.NonUniqueObjectException

    错误如下: 2017-3-29 15:17:52~ERROR~org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperV ...

  6. Exception 06 : org.hibernate.NonUniqueObjectException: A different object with the same identifier value was already associated with the session :

    异常名称: org.hibernate.NonUniqueObjectException: A different object with the same identifier value was ...

  7. org.hibernate.NonUniqueObjectException: a different object with the same identifier value was already associated with the session异常解决办法

    org.hibernate.NonUniqueObjectException: a different object with the same identifier value was alread ...

  8. org.hibernate.NonUniqueObjectException 原因及解决办法

    问题 使用hibernate更新对象时,出现如下错误: org.hibernate.NonUniqueObjectException: a different object with the same ...

  9. org.hibernate.NonUniqueObjectException:a different object with the same identifier value was alread

    转自: http://blog.csdn.net/zzzz3621/article/details/9776539 看异常提示意思已经很明显了,是说主键不唯一,在事务的最后执行SQL时,session ...

随机推荐

  1. 十二生肖&天干地支

    看相:http://baike.baidu.com/view/833122.htm?fr=aladdin 八字:http://baike.baidu.com/view/17127.htm?fr=ala ...

  2. Delphi的ListView自动排序

    private SortCol: Integer; SortWay: Integer; procedure TForm1.LVweColumnClick(Sender: TObject; Column ...

  3. endnote X7参考文献缩进设置

    首先打开[endnote]软件,在"edit-output styles-edit(你所选择的文献格式名称)"对话框中点击"bibliography-layout&quo ...

  4. [ Android 五种数据存储方式之四 ] —— ContentProvider存储数据

    Android这个系统和其他的操作系统还不太一样,我们需要记住的是,数据在Android当中是私有的,当然这些数据包括文件数据和数据库数据以及一些其他类型的数据.那这个时候有读者就会提出问题,难道两个 ...

  5. 使用 visualstudio code 编辑器调试执行在 homestead 环境中的 laravel 程序

    由于之前做 .net 开发比较熟悉 visualstudio,所以自 visualstudio code 发布后就一直在不同场合使用 vscode ,比如前端.node等等.最近在做 laravel ...

  6. 蓝桥网试题 java 基础练习 杨辉三角形

    ----------------------------------------------------------- ---------------------------------------- ...

  7. class path resource [config.xml] cannot be opened because it does not exist

    初学Spring在用Resource rs=new ClassPathResource("applicationContext.xml");时老是遇到这个错误.后来发现用Appli ...

  8. C#实现HttpUtility.UrlEncode输出大写字母

    在c#中,HttpUtility.UrlEncode("www+mzwu+com")编码结果为www%2bmzwu%2bcom,在和Java开发的平台做对接的时候,对方用用url编 ...

  9. block和delegate的区别

    代理  可读性高  大部分可以属性 block   写的代码少 一般作为参数通知   占用资源 无论是block还是delegate模式本质上都是回调,使用block,其优点是回调的block代码块直 ...

  10. React Native 之 网络请求

    前言 学习本系列内容需要具备一定 HTML 开发基础,没有基础的朋友可以先转至 HTML快速入门(一) 学习 本人接触 React Native 时间并不是特别长,所以对其中的内容和性质了解可能会有所 ...