新建了一个项目使用了maven,搜spring和hibernate的dependency的时候就直接使用了最新的包。查到资料说,Hibernate4和Spring搭配已经不能使用Spring的HibernateDaoSupport了,所以在与数据库交互的DAO层中需要使用SessionFactory.getCurrentSession()的方式来获取Session来进行增删改查。SessionFacoty使用的是Spring ORM的org.springframework.orm.hibernate4.LocalSessionFactoryBean。
第一个问题:is not valid without active transaction
在只是用Hibernate的时候我们将SessionFactory中的属性名为hibernate.current_session_context_class的值设置为thread,目的是希望可以通过SessionFactory.getCurrentSession()来获得当前的数据库Session会话,然后通过Session.beginTransaction()开启一个事务执行数据库操作。在结合Spring4之后,我们会配置一个org.springframework.orm.hibernate4.HibernateTransactionManager的事务管理器,这时我们的getCurrentSession()获取到的是Spring事务中的Session,不用再beginTransaction()了。属性hibernate.current_session_context_class的值也要相应的改为org.springframework.orm.hibernate4.SpringSessionContext,此值为默认值,直接删除hibernate.current_session_context_class也可。
<prop key="hibernate.current_session_context_class">thread</prop> 改为: <prop key="hibernate.current_session_context_class">org.springframework.orm.hibernate4.SpringSessionContext</prop> 或 删除此配置项
第二个问题:Could not obtain transaction-synchronized Session for current thread
在项目运行起来之前可能会需要加载数据库的信息,我使用了@PostConstruct来在加载数据库存放的权限信息。但是在运行@PostConstruct 标记的方法时,事务还没有开启,所以方法中的查询数据库方法getCurrentSession().createQuery().list()会报错。getCurrentSession()获取到的Session是在事务中的,而我要做的查询操作可以不用在事务中,既然事务还没有开启,我就使用openSession()的方法新建一个没有事务的Session,这样执行查询就不会报错了。
sessionFactory.getCurrentSession().createQuery(hql).list(); 改为: sessionFactory.openSession().createQuery(hql).list();
注意:使用openSession()之后一定要close()。
如果servlet.xml中的controller包扫描配置<context:component-scan base-package=”com.spoon.*” />将service层包含进去了,也会报这个错误,可能是扫描的冲突?目前不太清楚!
第三个问题:No mapping found for HTTP request with URI
使用Spring4.1.7时没有问题,由于要加入Spring-websocket来支持页面聊天,所以将Spring全部换成了4.2.0版本,结果就造成了controller没能扫描,出现了访问路径找不到的问题。经查询,将<context:component-scan base-packege=”com.spoon.web”/>换成了上级目录<context:component-scan base-packege=”com.spoon.*”/>就可以了,目前还不知道两个版本为什么在这个地方出现了问题。
转载请注明来源:http://www.foospoon.com/?p=63
暂无评论