0

I think @Transactional doesn't work with other annotations such @Controller or I have a problem and confusion with component-scan because i get this error :

org.hibernate.HibernateException: No Session found for current thread

Here's my configuration files :

mvc-dispatcher-servlet.xml

<context:component-scan base-package="controller"/>
<mvc:annotation-driven />

Hibernate.xml

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

   <bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
      ....
   </bean>

   <bean id="dataSource" class="org.apache.tomcat.dbcp.dbcp2.BasicDataSource">
      ...
   </bean>

   <bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
      ...
   </bean>

   <tx:annotation-driven transaction-manager="transactionManager" />

My test Controller

@Transactional
@Controller
public class Test {

    @Autowired
    private SessionFactory sessionFactory;

    @RequestMapping(value="/") 
    public String test() {
        ...
        sessionFactory.getCurrentSession().get(Region.class,1);
        ...
    }
    ...
}

My web.xml

<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>hibernate.xml</param-value>
</context-param>


<servlet>
    <servlet-name>mvc-dispatcher</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>mvc-dispatcher-servlet.xml</param-value>
    </init-param> 
    <load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
    <servlet-name>mvc-dispatcher</servlet-name>
    <url-pattern>/</url-pattern>
</servlet-mapping>
Hayi
  • 6,972
  • 26
  • 80
  • 139

1 Answers1

5

You transactional configuration applies to your root context which also component scans your controller package.

Basically you end up with

  • Root Context: @Controller beans with transactional behavior
  • Servlet Context: @Controller beans without transactonal behavior

You have duplicate beans. However, the DispatcherServlet constructs its MVC stack from the @Controller beans in the Servlet Context and those are not advised by the transaction interceptor.

You could move your transactional configuration to your servlet context or you could move the transactional behavior to @Service beans declared in the Root Context.

Related:

Community
  • 1
  • 1
Sotirios Delimanolis
  • 274,122
  • 60
  • 696
  • 724
  • It might be worth having a canonical beans-in-different-contexts Spring Q&A. – chrylis -cautiouslyoptimistic- Jun 29 '14 at 02:59
  • @chrylis I agree with you. The `Application context vs servlet context` questions linked in the linked q/a might be good starting point. You did that other good question/answer on `null` `@Autowired`, you might as well do this one. – Sotirios Delimanolis Jun 29 '14 at 03:03
  • I certainly don't understand it as well (part of why I like Spring Boot so much), but I can make an attempt if you're not up for it. – chrylis -cautiouslyoptimistic- Jun 29 '14 at 03:05
  • @chrylis If you make it a community post, I'll consider adding to it. I'm extremely vege right now :| – Sotirios Delimanolis Jun 29 '14 at 03:07
  • 1
    **1-** i move my **transactional** configuration to my servlet context and it works thanks a lot man. **2-** but i didn't understand the second option can you explain it more because i don't have `@Service` beans **3-** How can i see the beans generated by spring ? **4-** How can i avoid having duplicate beans ? i'm afraid it causes me performances issue. if you can edit the answer it will be very good :) – Hayi Jun 29 '14 at 03:51
  • @user3756879 **2-** Controllers are meant to set up and delegate to the model. You shouldn't do any business logic there. So I was recommending refactoring the code you want to be transactional and move it to `@Service` beans which you can declare in the root context. **3-** You can turn your logs on to TRACE-DEBUG level. What you have to understand how `ApplicationContext`(s) is(are) loaded in a Spring MVC web-app. If you check the linked question, you'll find more in depth discussion. **4-** Yes, you don't want duplicate beans. You have to be careful how you declare them. See the link. – Sotirios Delimanolis Jun 29 '14 at 04:21
  • **(2) -** why ? i feel comfortable with treating business at controller level and I call dao layer simpily, because if i want just load a entity why i have to create a new service layer for it ? **(3) -** I'm new at logging so i create a new question [link](http://stackoverflow.com/questions/24478592) – Hayi Jun 29 '14 at 17:41
  • @user3756879 **2** Separation of concerns. If your logic grows, you don't want to have it in the Controllers. It's up to you, just a suggestion. – Sotirios Delimanolis Jun 29 '14 at 17:46
  • yes maybe because my logics is not big for now but i don't want declare a lot of interfaces i'm little confused about this here's a question i'v create yesterday i need your point if it's possible http://stackoverflow.com/questions/24470573 – Hayi Jun 29 '14 at 17:56