I have @Transactional @Controller, but its methods are launched using the Spring MVC framework without a transaction. In the exception trace, I do not find a transaction advisor that catches the call:
org.hibernate.HibernateException: No Session found for current thread
org.springframework.orm.hibernate4.SpringSessionContext.currentSession(SpringSessionContext.java:106)
org.hibernate.internal.SessionFactoryImpl.getCurrentSession(SessionFactoryImpl.java:1014)
org.example.businesslogic.MyController.userLoggedIn(SwiperRest.java:48)
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
java.lang.reflect.Method.invoke(Method.java:483)
org.springframework.web.method.support.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:215)
org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:132)
org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:104)
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandleMethod(RequestMappingHandlerAdapter.java:749)
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:689)
org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:83)
org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:938)
On the other hand, the log clearly indicates that controller methods were detected as transactional:
DEBUG o.s.b.f.s.DefaultListableBeanFactory - Returning cached instance of singleton bean 'org.springframework.transaction.config.internalTransactionAdvisor'
DEBUG o.s.b.f.s.DefaultListableBeanFactory - Returning cached instance of singleton bean 'metaDataSourceAdvisor'
DEBUG o.s.t.a.AnnotationTransactionAttributeSource - Adding transactional method 'MyController.userLoggedIn' with attribute: PROPAGATION_REQUIRED,ISOLATION_DEFAULT; ''
DEBUG o.s.a.f.a.InfrastructureAdvisorAutoProxyCreator - Creating implicit proxy for bean 'myController' with 0 common interceptors and 1 specific interceptors
DEBUG o.s.a.f.CglibAopProxy - Creating CGLIB proxy: target source is SingletonTargetSource for target object [org.example.businesslogic.MyController@7c0f1b7c]
DEBUG o.s.a.f.CglibAopProxy - Unable to apply any optimisations to advised method: public java.lang.String org.example.businesslogic.MyController.userLoggedIn(java.lang.String,java.lang.String)
DEBUG o.s.t.a.AnnotationTransactionAttributeSource - Adding transactional method 'MyController.locationProfiles' with attribute: PROPAGATION_REQUIRED,ISOLATION_DEFAULT; ''
DEBUG o.s.a.f.CglibAopProxy - Unable to apply any optimisations to advised method: public java.util.List org.example.businesslogic.MyController.locationProfiles(java.lang.String)
Excerpt from the controller class:
@Transactional
@Controller
@RequestMapping("/zendor")
public class MyController
{
@Autowired private SessionFactory sf;
@RequestMapping(method=POST, value="userLoggedIn")
public @ResponseBody String userLoggedIn(@RequestParam String u_id, @RequestParam String d_id) {
Session hb = sf.getCurrentSession();
...
}
}
This is my web application initializer, I do not have web.xml:
public class WebApplicationInitializer extends AbstractAnnotationConfigDispatcherServletInitializer
{
@Override
protected Class<?>[] getRootConfigClasses() { return new Class[] { RootConfig.class }; }
@Override
protected Class<?>[] getServletConfigClasses() { return new Class[] { WebMvcConfig.class }; }
@Override
protected String[] getServletMappings() { return new String[] { "/" }; }
@Override public void onStartup(ServletContext ctx) throws ServletException {
ctx.setInitParameter("spring.profiles.active", "production");
super.onStartup(ctx);
}
}
This is the link to the root configuration:
package org.example.config;
@Configuration
@ComponentScan
public class RootConfig
{
}
It is in the same package as these, which fall into the default scan range of components:
@Configuration
@EnableWebMvc
@ComponentScan("org.example.businesslogic")
public class WebMvcConfig extends WebMvcConfigurationSupport
{
}
@Configuration
@EnableTransactionManagement
@ComponentScan("org.example.businesslogic")
public class DataConfig implements TransactionManagementConfigurer
{
@Autowired private DataSource dataSource;
...
}
When the same configuration is used by Spring -test SpringJUnit4ClassRunner, the methods get recommendations and transactions work.
userLoggedIn @Autowired @Transactional @Component, .
?
Spring 4.0.5.
1
, , WebMvcConfig, .
, , ,
@Override
protected Class<?>[] getServletConfigClasses() { return new Class[] { WebMvcConfig.class }; }
@Override
protected Class<?>[] getServletConfigClasses() { return null; }
: may not be empty or null. , null rootConfigClasses RootConfig servletConfigClasses, , " ".
2
, , Spring Web Security, , -, , SecurityWebApplicationInitializer, , , , , -. , root webapp, root webapp .