自己写了一个springMVC+hibernate的博客
每个DispatchServlet会有一个自己的上下文,称为子上下文,它也保存在 ServletContext中,key 是"org.springframework.web.servlet.FrameworkServlet.CONTEXT"+Servlet名称。spring4 与 hibernate5整合之后,添加博客操作无论如何都不能成功,查看日志和debug发现,要么是transation无法绑定current session,要么就报transation是read-only的错误
可是我的事务明明是配置的read-only = false 啊。网上找了很多办法都失败了,包括在web.xml加session view过滤器;弃用hibernateTemplate和hibernateDaoSupport,选择直接注入sessionFactory,并且直接由getCurrentSession获取原生hibernate session,再进行save()操作 。还是不行。
后来发现问题是上下文问题(wtf ?),spring 本身是有个webApplicationContext上下文的存储在服务器sevletContext中,称之为父上下文。而对应于springMVC每个DispatchServlet(是的,可以配置多个)会有一个自己的上下文,称为子上下文,它也保存在 ServletContext中,key 是"org.springframework.web.servlet.FrameworkServlet.CONTEXT"+Servlet名称。
事务是配置在service层的,但执行注解扫描的时候controller\service\dao是在springMVC配置文件里扫描的,由此可知service bean 是绑定在了子上下文里,而对于spring事务的管理又是与spring mvc独立的,即配置在spring配置文件里,这时候transationManage是配置在父上下文里的。子上下文可以访问父上下文,但是父上下文不能访问子上下文。所以自然service层的事务管理是不能成功的。我把扫描service(需要dao对象的注入)的工作和扫描dao包的工作配置在spring配置文件里,即放在父上下文,这个时候事务就可以成功执行。问题解决!
关于父子上下文的问题可参考: