尝试用spring+spring mvc+hibernate搭一个简单的项目,最终数据展示的时候hibernate一直报No Hibernate Session bound to thread, and configuration does not allow creation of non-transactional one here] with root cause的错误,网上找了好多都是说没有配置
<tx:annotation-driven transaction-manager="transactionManager"/>
但是我是有配置的,非常崩溃,请教下大家。
sessionFactory的配置如下:
<!-- 配置session工厂 -->
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource">
<ref bean="defaultDataSource" />
</property>
<property name="mappingLocations">
<list>
<value>classpath:/com/recommend/effect/**/model/*.hbm.xml</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.Oracle10gDialect</prop>
<prop key="hibernate.show_sql">true</prop>
<!-- <prop key="hibernate.hbm2ddl.auto">update</prop> -->
<prop key="hibernate.cache.provider_class">org.hibernate.cache.HashtableCacheProvider</prop>
</props>
</property>
</bean>
事务配置如下:
<!-- 配置事务管理 -->
<bean id="transactionManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory">
<ref bean="sessionFactory" />
</property>
</bean>
<!-- 开启注解事务 -->
<tx:annotation-driven transaction-manager="transactionManager"/>
<tx:advice transaction-manager="transactionManager" id="defaultTransactionAdvice">
<tx:attributes>
<tx:method name="find*" propagation="REQUIRED" read-only="true" />
<tx:method name="get*" propagation="REQUIRED" read-only="true" />
<tx:method name="query*" propagation="REQUIRED" read-only="true" />
<tx:method name="check*" propagation="REQUIRED" read-only="true" />
<tx:method name="load*" propagation="REQUIRED" read-only="true" />
<tx:method name="save*" propagation="REQUIRED" />
<tx:method name="add*" propagation="REQUIRED" />
<tx:method name="create*" propagation="REQUIRED" />
<tx:method name="insert*" propagation="REQUIRED" />
<tx:method name="update*" propagation="REQUIRED" />
<tx:method name="*" propagation="REQUIRED" />
</tx:attributes>
</tx:advice>
aop控制如下:
<!-- 服务AOP配置 -->
<aop:config expose-proxy="true">
<aop:pointcut id="systemTransactionPolicy"
expression="execution(* org.trustel.service.hibernate.*.*(..))"/>
<aop:advisor id="systemTransactionAdvisor" advice-ref="defaultTransactionAdvice"
pointcut-ref="systemTransactionPolicy" />
</aop:config>
<aop:config>
<aop:pointcut id="developFlowTransactionPolicy"
expression="execution(* com.recommend.*.service..*.*(..))" />
<aop:advisor id="developFlowTransactionAdvisor"
advice-ref="defaultTransactionAdvice" pointcut-ref="developFlowTransactionPolicy" />
</aop:config>
报错也就是获取currentSession
protected Query createQuery(String hql) {
Session session = getSessionFactory().getCurrentSession();
Query query = session.createQuery(hql);
return query;
}
很崩溃,又捣鼓了一下发现了问题,自己傻逼了。因为一开始忘记配置事物,后面补的时候这里补一点哪里补一点居然忘记了最开始的开放session
在web.xml中加入hibernate的过滤请求将session打开即可,配置如下。
<filter>
<filter-name>openSessionInViewFilter</filter-name>
<filter-class>
org.springframework.orm.hibernate3.support.OpenSessionInViewFilter
</filter-class>
</filter>
<filter-mapping>
<filter-name>openSessionInViewFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
既然除了问题,也就在这里做个总结把。
getCurrentSession出错检查这几个地方,一是上面这个在web.xml中配置开启session,(当然数据库那些数据源,sessionFactory等该配置的配置,不然哪来的事物)
二就去检查自己有没有配置事物管理,如我问题中配置那样配置即可。
三是去检查有没有开启注解事物,没有在spring配置文件中加上这样一条即可
<!-- 开启注解事务 -->
<tx:annotation-driven transaction-manager="transactionManager"/>
然后检查声明式事物管理的配置,注意其中的name属性看看有没有包含自己事物代码的方法find* 表示以find开头的方法
不大熟悉可以搜索下tx:advice
<tx:advice transaction-manager="transactionManager" id="defaultTransactionAdvice">
<tx:attributes>
<tx:method name="find*" propagation="REQUIRED" read-only="true" />
<tx:method name="get*" propagation="REQUIRED" read-only="true" />
<tx:method name="query*" propagation="REQUIRED" read-only="true" />
<tx:method name="check*" propagation="REQUIRED" read-only="true" />
<tx:method name="load*" propagation="REQUIRED" read-only="true" />
<tx:method name="save*" propagation="REQUIRED" />
<tx:method name="add*" propagation="REQUIRED" />
<tx:method name="create*" propagation="REQUIRED" />
<tx:method name="insert*" propagation="REQUIRED" />
<tx:method name="update*" propagation="REQUIRED" />
<tx:method name="*" propagation="REQUIRED" />
</tx:attributes>
</tx:advice>
再然后去检查下看看配置的aop控制有没有扫描到自己写了事物逻辑的代码文件。上述总结可能会有错误和不足,发现再纠正。
最后给自己一个提醒。练习在有系统的知识体系基础下会事半功倍,不然会做很多挺费时间的无用功