SpringLearner
SpringLearner

Reputation: 13844

How to resolve No Session found for current thread

I was trying to do generic way of implementation of DAO and I followed as per the Article

Following are my genericDaoImpl class

@SuppressWarnings("unchecked")
@Repository
public abstract class GenericDaoImpl<E, K extends Serializable> 
        implements GenericDao<E, K> {
    @Autowired
    private SessionFactory sessionFactory;

    protected Class<? extends E> daoType;

    /**
    * By defining this class as abstract, we prevent Spring from creating 
    * instance of this class If not defined as abstract, 
    * getClass().getGenericSuperClass() would return Object. There would be 
    * exception because Object class does not hava constructor with parameters.
    */
    public GenericDaoImpl() {
        Type t = getClass().getGenericSuperclass();
        ParameterizedType pt = (ParameterizedType) t;
        daoType = (Class) pt.getActualTypeArguments()[0];
    }

    protected Session currentSession() {
        return sessionFactory.getCurrentSession();
    }

    @Override
    public void add(E entity) {
        currentSession().save(entity);
    }

    @Override
    public void saveOrUpdate(E entity) {
        currentSession().saveOrUpdate(entity);
    }

    @Override
    public void update(E entity) {
        currentSession().saveOrUpdate(entity);
    }

    @Override
    public void remove(E entity) {
        currentSession().delete(entity);
    }

    @Override
    public E find(K key) {
        return (E) currentSession().get(daoType, key);
    }

    @Override
    public List<E> getAll() {
        return currentSession().createCriteria(daoType).list();
    }
}

GENERICDAO

public interface GenericDao<E,K> {
    public void add(E entity) ;
    public void saveOrUpdate(E entity) ;
    public void update(E entity) ;
    public void remove(E entity);
    public E find(K key);
    public List<E> getAll() ;
}

SERVICE CLASS

@Service
public class test {
    @Autowired
    TestPlanDao testPlanDao;
    @Transactional(propagation = Propagation.REQUIRED)
    public int saveTestPlan()
    {

        try
        {

        TestPlan tp=new TestPlan();

        tp.setTestplan_version(1);
        testPlanDao.saveTestPlan(tp);
        logger.info("testplan saved");
        return 1;
        }
        catch(Exception e)
        {
            e.printStackTrace();
            logger.error(e.getMessage(),e);
            return 0;
        }

    }

This is my daoImpl

@Repository
public class TestPlanDaoImpl extends GenericDaoImpl<TestPlan, Integer> implements TestPlanDao{



    @Override
    @Transactional
    public void saveTestPlan(TestPlan tp) {
        // TODO Auto-generated method stub
        add(tp);

    }

hibernate configuration xml

    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
        destroy-method="close">
        <property name="driverClassName" value="com.mysql.jdbc.Driver" />
        <property name="url" value="jdbc:mysql://${mysqlHost}/${mysqldatabase}" />

        <property name="username" value="${mysqlUserName}" />
        <property name="password" value="${mysqlPassword}" />
        <property name="removeAbandoned" value="true" />
        <property name="initialSize" value="20" />
        <property name="maxActive" value="30" />
        <property name="maxIdle" value="-1" />
        <property name ="testOnBorrow" value="true"/>
        <property name ="validationQuery" value="SELECT 1"/>
    </bean>

  <bean id="sessionFactoryConf"
        class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
        <property name="dataSource" ref="dataSource" />
        <property name="annotatedClasses">
            <list>

                    <value>com.test.model.TestPlan</value>

                </list>
        </property>
        <property name="hibernateProperties">
            <props>
                <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>

                <prop key="hibernate.transaction.auto_close_session">true</prop>
                <prop key="hibernate.hbm2ddl.auto">update</prop>
            </props>
        </property>
  </bean>  

I am not able to find the cause of

org.hibernate.HibernateException: No Session found for current thread
    at org.springframework.orm.hibernate4.SpringSessionContext.currentSession(SpringSessionContext.java:106)
    at org.hibernate.internal.SessionFactoryImpl.getCurrentSession(SessionFactoryImpl.java:988)

Upvotes: 11

Views: 3788

Answers (6)

Rupesh Agrawal
Rupesh Agrawal

Reputation: 695

you need to add following code in your hibernate configuration xml file

<tx:annotation-driven transaction-manager="transactionManager" />
<bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
     <!-- property should be wired with a Hibernate SessionFactory in your case it is  sessionFactoryConf -->
     <property name="sessionFactory" ref="sessionFactoryConf" />
</bean>

Upvotes: 6

Yassir
Yassir

Reputation: 23

This happens when you try to save changes on a Business Object after a transaction has already finished.

I think you should take a look to Spring Data JPA ? It has a lot more to offer than a generic DAO.

Upvotes: 1

G.Kuks
G.Kuks

Reputation: 11

<bean id="transactionManager"
    class="org.springframework.orm.hibernate3.HibernateTransactionManager">
    <property name="sessionFactory" ref="sessionFactoryConf" />
</bean>

Upvotes: 1

Vibhay Sachan
Vibhay Sachan

Reputation: 161

Remove @Transactional annotation from function and use it on the class level.

Upvotes: 2

Vinesh Sharma
Vinesh Sharma

Reputation: 31

You have to remove the @Transactional annotation from the Repository method , use only the @Transactional annotation on the service layer method.

   @Repository
 public class TestPlanDaoImpl extends GenericDaoImpl<TestPlan, Integer>   implements TestPlanDao{



     @Override
     @Transactional //Remove annotation from here
    public void saveTestPlan(TestPlan tp) {
     // TODO Auto-generated method stub
     add(tp);

 }

Upvotes: 3

Dalc
Dalc

Reputation: 1138

Did you try removing the following property :

<prop key="hibernate.transaction.auto_close_session">true</prop>

I believe that Hibernate will close the session too soon and resulting in your error. Since you use Spring TransactionManager, let it close the session.

Upvotes: 6

Related Questions