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.
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.
If someone could check if imports
are correct in 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$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>
dispatcher-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.");
}
}
Move this code from dispatcher-servlet.xml
<beans:bean id="regionsDao" class="facade.RegionsDaoImpl"/>
<beans:bean id="regionService" class="facade.RegionServiceImpl"/>
to 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
<context:component-scan base-package="facade" />
In your RegionServiceImpl
class the import should actually be:
import org.springframework.transaction.annotation.Transactional;
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")
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
So, just change this line
import javax.transaction.transactional
with
import org.springframework.transaction.annotation.Transactional
in RegionServiceImpl.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.