2016-07-15 4 views
10

Я пытался сделать общий способ реализации DAO и я следовал согласно ArticleКак не разрешить Нет Session найденный для текущего потока

После моего genericDaoImpl класса

@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 
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; 
     } 

    } 

Это мой 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 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> 

Я не могу найти причину

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) 
+0

Вы аннулировали свой метод 'saveTestPlan' вашего dao с помощью' Transactional'? вы не включили его в свой вопрос – Apostolos

+0

@Apostolos да я сделал, но забыл добавить в сообщение. Пожалуйста, проверьте обновленный вопрос – SpringLearner

+0

. Мне кажется, вам нужно либо поставить 'currentSession(). Save (entity);' внутри этого метода, либо объявить '@ Transactional' метод' add'. поскольку он вызывает другой транзакционный метод, вам тоже нужно это аннотировать. попробуйте это и скажите мне, если он работает – Apostolos

ответ

6

ли вы попробуйте удалитьследующее имущество:

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

Я считаю, что Hibernate закроет сессию слишком рано и приведет к вашей ошибке. Поскольку вы используете Spring TransactionManager, позвольте ему закрыть сеанс.

+0

Я попытался с этим решением, но все тот же – SpringLearner

+0

Хорошо, пожалуйста, обновите конфигурацию Spring в своем сообщении, потому что нам нужно это увидеть. В моем ответе я предположил, что вы правильно определили свой TransactionManager, как @Rupesh, в его ответе. Как с его ответом, так и с моим, удалите эту аннотацию '@ Transactional' в TestPlanDaoImpl, которая не нужна, она должна хорошо работать – Dalc

5

вам нужно добавить следующий код в файле XML конфигурации Hibernate

<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> 
+0

Это правильный ответ. –

3

Вы должны удалить аннотацию @Transactional из Хранилища метода используйте только @Transactional аннотацию на методе обслуживания слоя.

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

} 
+0

Пожалуйста, добавьте несколько пунктов, в противном случае это похоже на комментарий. – surajsn

2

Удалить @Transactional аннотацию из функции и использовать ее на уровне класса.

1

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

Было бы полезно, если бы вы могли добавить некоторый контекст, это упростит ваш ответ. –

1

Это происходит при попытке сохранить изменения на бизнес-объекта после того, как сделка уже завершена.

Я думаю, вы должны взглянуть на Spring Data JPA? Он предлагает гораздо больше возможностей, чем общий DAO.

Смежные вопросы