Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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)
like image 466
SpringLearner Avatar asked Jul 15 '16 13:07

SpringLearner


4 Answers

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.

like image 183
Dalc Avatar answered Nov 15 '22 17:11

Dalc


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>
like image 28
Rupesh Agrawal Avatar answered Nov 15 '22 18:11

Rupesh Agrawal


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);

 }
like image 28
Vinesh Sharma Avatar answered Nov 15 '22 16:11

Vinesh Sharma


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

like image 29
Vibhay Sachan Avatar answered Nov 15 '22 16:11

Vibhay Sachan