Я получаю HibernateException "Сессия Hibernate не привязана к потоку, и конфигурация не позволяет создавать нетранзакционный сеанс здесь" - PullRequest
2 голосов
/ 07 октября 2011

Несмотря на кучу подобных вопросов, здесь мне ничего не кажется полезным.Я получаю исключение при вызове 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>

Mydata.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 (я удалил операторы импорта, чтобы не перегружать вопрос):

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;
    }


}

Буду признателен за любую помощь в этом вопросе.

1 Ответ

6 голосов
/ 07 октября 2011

Я думаю, что проблема в том, что вы не получаете доступ к своему сервису через интерфейс. По умолчанию Spring использует основанные на интерфейсе Java прокси.

Кстати, трассировка стека не содержит никакого транзакционного вызова перехватчика.

См. Второе примечание под этим параграфом Spring Документация:

Атрибут proxy-target-class на элемент контролирует, для какого типа создаются транзакционные прокси классы с аннотацией @Transactional. Если Атрибут proxy-target-class имеет значение true, прокси на основе классов создано. Если proxy-target-class имеет значение false или если атрибут опущено, создаются стандартные прокси на основе интерфейса JDK. (Увидеть Раздел 7.6, «Механизмы прокси» для обсуждения различных типы прокси.)

Итак, либо введите интерфейсы для ваших транзакционных сервисов и DAO, либо используйте proxy-target-class="true".

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...