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
Spring: No Hibernate Session bound to thread, and configuration does not allow creation of non-transactional one here
提问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 imports
are 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 @Service
on your service impl class. In applicationContext.xml
add
你不需要<bean/>
RegionServiceImpl 因为你有@Service
你的服务 impl 类。在applicationContext.xml
加
<context:component-scan base-package="facade" />
In your RegionServiceImpl
class 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 中。