Spring:没有Hibernate Session绑定到线程,配置不允许在这里创建非事务性的

时间:2014-05-31 19:55:00

标签: java spring hibernate spring-mvc

我正在创建简单的Web应用程序来显示和添加行到我的oracle数据库(Regions表)。可悲的是,我在标题中得到例外。我见过与此相关的类似问题,遗憾的是没有任何帮助。

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

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

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

  

异常

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$9.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.access$100(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 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>
  

调度-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

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

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

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.");
    }
}

3 个答案:

答案 0 :(得分:2)

dispatcher-servlet.xml

移动此代码
<beans:bean id="regionsDao" class="facade.RegionsDaoImpl"/>

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

applicationContext.xml

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

对于RegionServiceImpl,您不需要<bean/>,因为您的服务impl类上有@Service。在applicationContext.xml添加

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

RegionServiceImpl课程中,导入应该是:

import org.springframework.transaction.annotation.Transactional;

答案 1 :(得分:0)

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

答案 2 :(得分:0)

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

所以,只需更改此行

即可

导入javax.transaction.transactional

import org.springframework.transaction.annotation.Transactional

RegionServiceImpl中的