Spring – “No Session found for current thread” error in DAO when marking Service class as Transactional

annotationshibernatespringtransactions

Using Hibernate 4 and Spring 3.1. Just getting up and running with it so this may be a lack of understanding on my part. I have a method in a Service class which calls a method in a DAO class to retrieve some data using Hibernate. I annotate the Service method with @Transactional but get an error when calling getCurrentSession in the DAO method. If I annotate the DAO method with @Transactional as well then the data is successfully retrieved. I don't understand why though – I would have thought that the @Transactional annotation on the Service method would have created a Hibernate session, bound it to the thread and that this session would be returned in the DAO class when getCurrentSession is called. Can anyone explain why this is the case or if I am doing something wrong, thanks?

root-context.xml:

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

Service class:

public class BlahServiceImpl implements BlahService {

    @Transactional  
    public Blah GetMostRecentBlah() {
        BlahDAO blahDAO = DAOFactory.GetBlahDAO();
        return blahDAO.GetMostRecentBlah();
    }
}

DAO class:

private SessionFactory sessionFactory;

public void setSessionFactory(SessionFactory sessionFactory) {
    this.sessionFactory = sessionFactory;
}

public Blah GetMostRecentBlah() {
    return (Blah)sessionFactory.getCurrentSession().createQuery("from Blah where blahID = (select max(blahID) from Blah)").uniqueResult();
}

Error:

org.hibernate.HibernateException: No Session found for current thread
org.springframework.orm.hibernate4.SpringSessionContext.currentSession(SpringSessionContext.java:97)
org.hibernate.internal.SessionFactoryImpl.getCurrentSession(SessionFactoryImpl.java:1039)
com.blah.blah.DAO.BlahDAOImpl.GetMostRecentBlah(BlahDAOImpl.java:18)

Like I said, if I annotate the DAO function with @Transactioanl (as well as the Service method) this works but I don't understand why.

Best Answer

Two probable causes suggest themselves.

1) Your service bean is in a separate ApplicationContext, which doesn't have annotation-driven transactions enabled.

2) You're obtaining a reference to an instance of your service that's the raw instance instead of a proxied, and therefore transactional, instance.

To determine which is your problem, or determine if it's some other problem, show the context file that causes your service bean to be created, and show the code where you're getting an instance of your service.

Related Topic