Java Spring:没有 Hibernate Session 绑定到线程,并且配置不允许在此处创建非事务性会话

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/23974128/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-14 09:28:49  来源:igfitidea点击:

Spring: No Hibernate Session bound to thread, and configuration does not allow creation of non-transactional one here

javaspringhibernatespring-mvc

提问by ashur

I'm creating simple web app to display and add rows to my oracle database (Regions table). Sadly I'm getting exception as in title. I've seen similar question related to this unfortunately nothing helped me.

我正在创建简单的 Web 应用程序来显示行并将行添加到我的 oracle 数据库(区域表)。可悲的是,我收到了标题中的异常。我见过与此相关的类似问题,不幸的是没有任何帮助。

What I'm doing wrong ? I know it's related to transactions. I've annotated Service as @Transactional, however it doesn't solved my problem.

我做错了什么?我知道这与交易有关。我已将 Service 注释为@Transactional,但是它并没有解决我的问题。

If someone could check if importsare correct in Service.

如果有人可以检查是否imports是正确Service

If something more is needed please leave comment.

如果需要更多内容,请发表评论。

Exception

例外

WARNING:   StandardWrapperValve[dispatcher]: Servlet.service() for servlet dispatcher threw exception
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:64)
    at org.hibernate.impl.SessionFactoryImpl.getCurrentSession(SessionFactoryImpl.java:687)
    at facade.RegionsDaoImpl.getRegions(RegionsDaoImpl.java:31)
    at facade.RegionServiceImpl.getRegions(RegionServiceImpl.java:27)
    at controllers.RegionsController.listCustomers(RegionsController.java:31)
    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:606)
    at org.springframework.web.method.support.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:219)
    at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:132)
    at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:104)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandleMethod(RequestMappingHandlerAdapter.java:745)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:686)
    at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:80)
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:925)
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:856)
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:936)
    at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:827)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:687)
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:812)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:790)
    at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1682)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:318)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:160)
    at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:734)
    at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:673)
    at com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:99)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:174)
    at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:357)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:260)
    at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:188)
    at org.glassfish.grizzly.http.server.HttpHandler.runService(HttpHandler.java:191)
    at org.glassfish.grizzly.http.server.HttpHandler.doHandle(HttpHandler.java:168)
    at org.glassfish.grizzly.http.server.HttpServerFilter.handleRead(HttpServerFilter.java:189)
    at org.glassfish.grizzly.filterchain.ExecutorResolver.execute(ExecutorResolver.java:119)
    at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeFilter(DefaultFilterChain.java:288)
    at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeChainPart(DefaultFilterChain.java:206)
    at org.glassfish.grizzly.filterchain.DefaultFilterChain.execute(DefaultFilterChain.java:136)
    at org.glassfish.grizzly.filterchain.DefaultFilterChain.process(DefaultFilterChain.java:114)
    at org.glassfish.grizzly.ProcessorExecutor.execute(ProcessorExecutor.java:77)
    at org.glassfish.grizzly.nio.transport.TCPNIOTransport.fireIOEvent(TCPNIOTransport.java:838)
    at org.glassfish.grizzly.strategies.AbstractIOStrategy.fireIOEvent(AbstractIOStrategy.java:113)
    at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.run0(WorkerThreadIOStrategy.java:115)
    at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.access0(WorkerThreadIOStrategy.java:55)
    at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy$WorkerThreadRunnable.run(WorkerThreadIOStrategy.java:135)
    at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:564)
    at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.run(AbstractThreadPool.java:544)
    at java.lang.Thread.run(Thread.java:745)

applicationContext.xml

应用上下文.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:p="http://www.springframework.org/schema/p"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
       http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd
       http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd">


    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName">
            <value>oracle.jdbc.driver.OracleDriver</value>
        </property>
        <property name="url">
            <value>jdbc:oracle:thin:@localhost:1521:XE</value>
        </property>
        <property name="username">
            <value>hr</value>
        </property>
        <property name="password">
            <value>hr</value>
        </property>
    </bean>


    <bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
        <property name="dataSource">
            <ref bean="dataSource"/>
        </property>
        <property name="mappingResources">
            <list> 
                <value>persistence/Regions.hbm.xml</value> 
                <value>persistence/Countries.hbm.xml</value>
                <value>persistence/Locations.hbm.xml</value>
                <value>persistence/Departments.hbm.xml</value>
                <value>persistence/Employees.hbm.xml</value>
                <value>persistence/JobHistory.hbm.xml</value>
                <value>persistence/Jobs.hbm.xml</value>
            </list>
        </property>
        <!--<property name="configLocation">
        <value>/WEB-INF/hibernate.cfg.xml</value>
        </property> -->
        <property name="hibernateProperties">
            <props> 
                <prop key="hibernate.dialect">org.hibernate.dialect.OracleDialect</prop> 
            </props>
        </property>
    </bean>

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



    <tx:annotation-driven/>
</beans>

dispatcher-servlet.xml

调度程序-servlet.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/mvc"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xmlns:beans="http://www.springframework.org/schema/beans"
             xmlns:context="http://www.springframework.org/schema/context"
             xmlns:tx="http://www.springframework.org/schema/tx"
             xsi:schemaLocation="http://www.springframework.org/schema/mvc 
            http://www.springframework.org/schema/mvc/spring-mvc.xsd
            http://www.springframework.org/schema/beans 
            http://www.springframework.org/schema/beans/spring-beans.xsd
            http://www.springframework.org/schema/context 
            http://www.springframework.org/schema/context/spring-context.xsd">
    <!-- DispatcherServlet Context: defines this servlet's request-processing infrastructure -->
    <!-- Enables the Spring MVC annotation mechanism-->
    <annotation-driven />
    <context:annotation-config/> 
    <context:component-scan base-package="controllers" />
    <!-- Resolves views choosen for rendering to .jsp resources in the /WEB-INF/jsp directory -->
    <beans:bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <beans:property name="prefix" value="/WEB-INF/jsp/" />
        <beans:property name="suffix" value=".jsp" />
    </beans:bean>

    <beans:bean id="regionsDao" class="facade.RegionsDaoImpl"/>

    <beans:bean id="regionService" class="facade.RegionServiceImpl"/> 
</beans:beans>

RegionsController.java

区域控制器.java

package controllers;

import facade.RegionService;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import persistence.Regions;

@Controller
public class RegionsController {
    @Autowired
    private RegionService regionsService;

    @RequestMapping(value = "/", method = RequestMethod.GET)
    public String welcome(Model model) {
        return "index";
    }

    @RequestMapping(value = "/regions")
    public String listCustomers(Model model) {

        List<Regions> regionsList = regionsService.getRegions();
        model.addAttribute("regionsList", regionsList);
        model.addAttribute("region", new Regions());
        return "regions";
    }

    @RequestMapping(value = "/add_region")
    public String addRegion(@ModelAttribute Regions r) {
        regionsService.addRegion(r);
        return "redirect:/customers";
    }
}

RegionService.java RegionServiceImpl.java

RegionService.java RegionServiceImpl.java

package facade;

import java.util.List;
import persistence.Regions;

public interface RegionService {
    public List<Regions> getRegions();
    public void addRegion(Regions r);
}

/*******************************************/
package facade;

import java.util.List;
import javax.transaction.Transactional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import persistence.Regions;


@Service
@Transactional
public class RegionServiceImpl implements RegionService{

    @Autowired
    private RegionsDao regionsDao;

    @Override
    public List<Regions> getRegions() {
        return regionsDao.getRegions();
    }

    @Override
    public void addRegion(Regions r) {
        regionsDao.addRegion(r);
    }

}

RegionsDao.java RegionsDaoImpl.java

RegionsDao.java RegionsDaoImpl.java

package facade;

import java.math.BigDecimal;
import java.util.List;
import persistence.Regions;

public interface RegionsDao {
    public void addRegion(Regions r);
    public List<Regions> getRegions();
    public void removeRegion(BigDecimal regionId);
}

/**********************************************/
package facade;

import java.math.BigDecimal;
import java.util.List;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import persistence.Regions;

public class RegionsDaoImpl implements RegionsDao {
    @Autowired
    private SessionFactory sessionFactory;

    @Override
    public void addRegion(Regions r) {
        sessionFactory.getCurrentSession().save(r);
    }

    @Override
    public List<Regions> getRegions() {
        return sessionFactory.getCurrentSession().createQuery("from Regions r").list();
    }

    @Override
    public void removeRegion(BigDecimal regionId) {
        throw new UnsupportedOperationException("Not supported yet.");
    }
}

采纳答案by Andrei Stefan

Move this code from dispatcher-servlet.xml

将此代码从 dispatcher-servlet.xml

<beans:bean id="regionsDao" class="facade.RegionsDaoImpl"/>

<beans:bean id="regionService" class="facade.RegionServiceImpl"/>

to applicationContext.xml:

applicationContext.xml

<bean id="regionsDao" class="facade.RegionsDaoImpl"/>

You don't need <bean/>for RegionServiceImpl because you have @Serviceon your service impl class. In applicationContext.xmladd

你不需要<bean/>RegionServiceImpl 因为你有@Service你的服务 impl 类。在applicationContext.xml

<context:component-scan base-package="facade" />

In your RegionServiceImplclass the import should actually be:

在您的RegionServiceImpl课程中,导入实际上应该是:

import org.springframework.transaction.annotation.Transactional;

回答by NewlessClubie

My guess is that your @Transactional service was not correctly instrumented by Spring AOP system. This can be verified by putting a breakpoint inside transactional method and inspecting the call stack. Spring generates proxy classes with CGLIB so if everything worked correctly you should see some unusual class names (look for "$EnhancerByCGLIB")

我的猜测是您的 @Transactional 服务没有被 Spring AOP 系统正确检测。这可以通过在事务方法中放置断点并检查调用堆栈来验证。Spring 使用 CGLIB 生成代理类,因此如果一切正常,您应该会看到一些不寻常的类名(查找“$EnhancerByCGLIB”)

回答by Pirulino

In service object you are importing the wrong transactional annotation. The one you are using is java native (EJB), the spring one is: org.springframework.transaction.annotation.Transactional

在服务对象中,您导入了错误的事务注释。您使用的是 java native (EJB),spring 是:org.springframework.transaction.annotation.Transactional

So, just change this line

所以,只需改变这一行

import javax.transaction.transactional

导入 javax.transaction.transactional

with

import org.springframework.transaction.annotation.Transactional

导入 org.springframework.transaction.annotation.Transactional

in RegionServiceImpl.

在 RegionServiceImpl 中。