【问题标题】:I am receiving HibernateException "No Hibernate Session bound to thread, and configuration does not allow creation of non-transactional one here"我收到 HibernateException“没有绑定到线程的 Hibernate 会话,并且配置不允许在此处创建非事务性会话”
【发布时间】:2011-10-07 18:16:41
【问题描述】:

尽管这里有很多类似的问题,但对我来说似乎没有任何用处。当我调用 sessionFactory.getCurrentSession().createQuery("from Strings").list(); 时出现异常;

这是我的 root-context.xml:

<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context" xmlns:jee="http://www.springframework.org/schema/jee" xmlns:lang="http://www.springframework.org/schema/lang" xmlns:p="http://www.springframework.org/schema/p" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:util="http://www.springframework.org/schema/util" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee.xsd http://www.springframework.org/schema/lang http://www.springframework.org/schema/lang/spring-lang.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd">

<context:annotation-config/>

<context:component-scan base-package="org.vadim.testmvc.dao"/>
<context:component-scan base-package="org.vadim.testmvc.service"/>

<import resource="data.xml"/>

</beans>

我的数据.xml:

<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context" xmlns:jee="http://www.springframework.org/schema/jee" xmlns:lang="http://www.springframework.org/schema/lang" xmlns:p="http://www.springframework.org/schema/p" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:util="http://www.springframework.org/schema/util" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee.xsd http://www.springframework.org/schema/lang http://www.springframework.org/schema/lang/spring-lang.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd">

<tx:annotation-driven transaction-manager="transactionManager"/>

<bean id="transactionManager"     class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory"/>
</bean>

<bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<property name="basename" value="classpath:messages"/>
<property name="defaultEncoding" value="UTF-8"/>
</bean>

<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer" p:location="/WEB-INF/jdbc.properties"/>

<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource" p:driverClassName="${jdbc.driverClassName}" p:url="${jdbc.databaseurl}" p:username="${jdbc.username}" p:password="${jdbc.password}"/>

<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="configLocation">
<value>classpath:hibernate.cfg.xml</value>
</property>
<property name="configurationClass">
<value>org.hibernate.cfg.AnnotationConfiguration</value>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.dialect">${jdbc.dialect}</prop>
<prop key="hibernate.connection.charSet">UTF-8</prop>
</props>
</property>
</bean>
</beans>

TestController.java(我删除了 import 语句以免问题重载):

package org.vadim.testmvc;

@Controller
public class TestController {

@Autowired
    TestService testservice;

List<String> list = new LinkedList<String>();
int i=0;

@RequestMapping("/")
public String hello() {
    return "redirect:/helloworld";
}

@RequestMapping(value = "/helloworld")
String listWord(Map<String, Object> map){
    map.put("addRepeat", new Strings());
    map.put("listStrings", testservice.listStrings());
    return "helloworld";
}

@RequestMapping(value="/repeat", method = RequestMethod.POST)
String addRepeat(@ModelAttribute("addRepeat") Strings strings, BindingResult result) {
    testservice.addStrings(strings);
    return "redirect:/helloworld";
}
}

TestService.java:

package org.vadim.testmvc.service;

@Service
public class TestService {

@Autowired
TestDAO testdao;

@Transactional
public List<Strings> listStrings(){
    return testdao.listStrings();
}

@Transactional
public void addStrings(Strings strings){
    testdao.addStrings(strings);
}
}

最后是 TestDAO.java:

package org.vadim.testmvc.dao;

@Transactional
@Repository
public class TestDAO{

@Autowired
private SessionFactory sessionFactory;

public void addStrings(Strings strings){
    sessionFactory.getCurrentSession().save(strings);
}

@SuppressWarnings("unchecked")
public List<Strings> listStrings(){
    return sessionFactory.getCurrentSession().createQuery("from Strings").list();
}
}

异常发生后的堆栈:

SEVERE: Servlet.service() for servlet [appServlet] in context with path [/TestMVC] threw exception [Request processing failed; nested exception is org.hibernate.HibernateException: No Hibernate Session bound to thread, and configuration does not allow creation of non-transactional one here] with root cause
org.hibernate.HibernateException: No Hibernate Session bound to thread, and configuration does not allow creation of non-transactional one here
at org.springframework.orm.hibernate3.SpringSessionContext.currentSession(SpringSessionContext.java:63)
at         org.hibernate.impl.SessionFactoryImpl.getCurrentSession(SessionFactoryImpl.java:544)
at org.vadim.testmvc.dao.TestDAO.listStrings(TestDAO.java:23)
at org.vadim.testmvc.service.TestService.listStrings(TestService.java:18)
at org.vadim.testmvc.TestController.listWord(TestController.java:30)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:601)
at     org.springframework.web.bind.annotation.support.HandlerMethodInvoker.invokeHandlerMethod(HandlerMethodInvoker.java:176)
at org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.invokeHandlerMethod(AnnotationMethodHandlerAdapter.java:426)
at org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.handle(AnnotationMethodHandlerAdapter.java:414)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:790)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:719)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:644)
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:549)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:621)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:304)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:224)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:462)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:164)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:100)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:851)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
at com.springsource.insight.collection.tcserver.request.HttpRequestOperationCollectionValve.invoke(HttpRequestOperationCollectionValve.java:84)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:405)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:278)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:515)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:300)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)
at java.lang.Thread.run(Thread.java:722)

hibernate.cfg.xml:

<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<mapping class="org.vadim.testmvc.model.Strings"/>
</session-factory>
</hibernate-configuration>

Strings.java:

package org.vadim.testmvc.model;

@Entity
@Table(name="STRINGS")
public class Strings {
    @Id
    @Column(name="ID")
    @GeneratedValue
    private Integer id;

    public Integer getId(){
        return id;
    }

    @Column(name="TEXT")
    private String text;

    public String getText(){
        return text;
    }

    public void setText(String text){
        this.text=text;
    }


}

感谢您在此问题上的所有帮助。

【问题讨论】:

    标签: java hibernate session


    【解决方案1】:

    我认为问题在于您没有通过接口访问您的服务。默认情况下,Spring 使用基于 Java 接口的代理。

    顺便说一句,堆栈跟踪不包含任何事务拦截器调用。

    参见this paragraph of the Spring 文档下的第二条注释:

    proxy-target-class 属性 元素控制为什么类型的事务代理创建 使用@Transactional 注释注释的类。如果 proxy-target-class 属性设置为 true,基于类的代理是 创建的。如果 proxy-target-class 为 false 或属性为 如果省略,则会创建标准的基于 JDK 接口的代理。 (看 第 7.6 节,“代理机制”,讨论不同的 代理类型。)

    所以,要么为你的事务服务和 DAO 引入接口,要么使用proxy-target-class="true"

    【讨论】:

    • 这就是重点,感谢您的帮助!我刚刚为 TestService 和 TestDAO 添加了两个接口,它有帮助!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多