No Hibernate Session bound to Thread非事物解决方式
这个问题 百度能搜到很多答案,多数都是说事物配置的,但是我按照很多解决方案都没能达到目的.问了小亮大神后才明白了为什么
首先贴一下我的beans.xml(对于dataSource class的选择似乎有很多)
1 <bean id="dataSource" 2 class="org.springframework.jdbc.datasource.DriverManagerDataSource" 3 destroy-method="close"> 4 <property name="driverClassName" value="com.mysql.jdbc.Driver" /> 5 <property name="url" value="jdbc:mysql://localhost:3306/credit_report" /> 6 <property name="username" value="root" /> 7 <property name="password" value="root" /> 8 </bean> 9 10 <bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean"> 11 <property name="dataSource" ref="dataSource" /> 12 <property name="mappingResources"> 13 <list> 14 <value>com/report/model/Report.hbm.xml</value> 15 </list> 16 </property> 17 18 19 <property name="hibernateProperties"> 20 <props> 21 <prop key="hibernate.dialect"> 22 org.hibernate.dialect.MySQLInnoDBDialect 23 </prop> 24 <prop key="hibernate.show_sql"> 25 true 26 </prop> 27 <prop key="current_session_context_class"> 28 thread 29 </prop> 30 </props> 31 </property> 32 </bean> 33 34 <!-- service Impl --> 35 <bean id="reportServiceHibernateImpl" class="com.report.service.impl.ReportServiceHibernateImpl"> 36 <property name="sessionFactory"> 37 <ref bean="sessionFactory" /> 38 </property> 39 </bean> 40 41 <bean id="reportServiceImpl" class="com.report.service.impl.ReportServiceImpl"> 42 </bean> 43 44 <!-- Action --> 45 <bean name="/report" class="com.report.action.ReportAction"> 46 <property name="service"> 47 <ref bean="reportServiceHibernateImpl" /> 48 </property> 49 <property name="serviceMyBatis" > 50 <ref bean="reportServiceImpl"/> 51 </property> 52 </bean>
在用struts-config.xml时,注意<action-mapping><action>中的type配置,不加入Spring时配置为ReportAction类就可以了,再加入Spring后需要配置成这样
<struts-config> <form-beans> <form-bean name="reportForm" type="com.report.form.ReportForm"/> </form-beans> <action-mappings> <action path="/report" type="org.springframework.web.struts.DelegatingActionProxy" name="reportForm" scope="request"></action> </action-mappings> <controller processorClass="org.springframework.web.struts.DelegatingRequestProcessor"> </controller> <message-resources parameter="com.test.struts.ApplicationResources" /> <plug-in className="org.springframework.web.struts.ContextLoaderPlugIn"> <set-property property="contextConfigLocation" value="WEB-INF/classes/beans.xml" /> </plug-in> </struts-config>
因为我是先用Hibernate做的service实现,再加入Spring控制,本想在不修改Hibernate实现类的情况下,只用Spring管理dataSource和sessionFactory
但是配置完成之后每次都会报No Hibernate Session bound to Thread这个错,原因是因为:
* 用Spring配置dataSource和管理Hibernate的sessionFactory时,
* 由于Spring内部对sessionFactory做了改动,所以不能直接注入beans.xml配置的sessionFactory,
我是在ReportServiceHibernateImpl实现类中想注入sessionFactory但是每次注入都是null,很不解,感谢小亮的耐心解答
* 推荐使用HibernateTemplate和HibernateDaoSupport
* 另外 , 查询有两种方式(具体代码请参照ExtJs2.1项目中的ReportServiceHibernateImpl具体实现方式)
* 1.使用HibernateTemplate.find()这种方式好像不支持分页(无法传入start)
* 2.(需在继承HibernateDaoSupport后使用)session = this.getSession,继续使用Query对象查询(query可以设置start和limit)
两个典型方法作为事例
@Override public List<Report> selectForListFuzzy(ReportForm report) { List<Report> list = new ArrayList<Report>(); String name = report.getName(); String cardId = report.getCardId(); String cardType = report.getCardType(); String content = report.getContent(); HibernateTemplate tpl = new HibernateTemplate(getSessionFactory()); String sql = "select R from Report R where 1 = 1 "; if (null != name && "" != name) { sql += " and name like '%" + name + "%'"; } if (null != cardId && "" != cardId) { sql += " and cardId like '%" + cardId + "%'"; } if (null != cardType && "" != cardType) { sql += " and cardType = '" + cardType + "'"; } list = tpl.find(sql); log.warn("list.size() == " + list.size()); return list; } @Override public List<Report> selectForListFuzzyPage(ReportForm report) { List<Report> list = new ArrayList<Report>(); String name = report.getName(); String cardId = report.getCardId(); String cardType = report.getCardType(); String content = report.getContent(); int start = report.getStart(); int limit = report.getLimit(); HibernateTemplate tpl = new HibernateTemplate(getSessionFactory()); // session.beginTransaction(); String sql = "select R from Report R where 1 = 1 "; if (null != name && "" != name) { sql += " and name like '%" + name + "%'"; } if (null != cardId && "" != cardId) { sql += " and cardId like '%" + cardId + "%'"; } if (null != cardType && "" != cardType) { sql += " and cardType = '" + cardType + "'"; } Query query = this.getSession().createQuery(sql); query.setFirstResult(start); query.setMaxResults(limit); list = query.list(); log.warn("list.size() == " + list.size()); return list; }