Spring使用OpenSessionInViewFilter解决Hibernate的lazy延时

今天面试的时候,对方谈起了使用OpenSessionInViewFilter解决hibernate懒加载异常的方式,当时就觉得不妥,这跟hibernate的lazy设计理念有冲突的,于是查资料并分析如下:

OpenSessionInViewFilter调用流程:

request(请求)->open session并开始transaction->controller->View(Jsp)->结束transaction并close session.

session的生命周期比事务要长若这期间所有事务性操作都在复用这同一个session,会产生一些“怪问题”:
例如出现如下错误:
     org.springframework.dao.InvalidDataAccessApiUsageException: Write operations are not allowed in read-only mode (FlushMode.NEVER) - turn your Session into FlushMode.AUTO or remove 'readOnly' marker from transaction definition
分析原因:OpenSessionInViewFilter 在把session绑在当前线程上的时候,会把session的flush mode 设为FlushMode.NEVER,因此,如果某个方法没有事务或者有只读事务,则不能对session做insert,update,delete操 作,除非事先把session的flush mode手动设为auto
方案:
1、将singleSession设为false,这样只要改 web.xml,缺点是Hibernate Session的Instance可能会大增,使用的JDBC Connection量也会大增,如果Connection Pool的maxPoolSize设得太小,很容易就出问题。<!-- singleSession默认为true,若设为false则等于没用OpenSessionInView -->
2、在控制器中自行管理Session的FlushMode,麻烦的是每个有Modify的Method都要多几行程式
session.setFlushMode(FlushMode.AUTO);
session.update(user);
session.flush();
3、Extend OpenSessionInViewFilter,Override protected Session getSession(SessionFactory sessionFactory),将FlushMode直接改为Auto。
4、让方法受Spring的事务控制(service和配置文件对应)

你可能感兴趣的:(Spring使用OpenSessionInViewFilter解决Hibernate的lazy延时)