2016-07-15 179 views
10

stavo cercando di fare modo generico di attuazione del DAO e ho seguito come da ArticleCome risolvere Nessun sessione trovata per thread corrente

seguito sono la mia classe 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() ; 
} 

classe di servizio

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

    } 

Questo è il mio 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); 

    } 

configurazione 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> 

io non sono in grado di trovare la causa di

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

hai annotato il tuo metodo 'saveTestPlan' del tuo dao con' Transactional'? non l'hai incluso nella tua domanda – Apostolos

+0

@ Postolos sì, ma ho dimenticato di aggiungere nel post. Si prega di verificare la domanda aggiornata – SpringLearner

+0

penso che sia necessario mettere il 'currentSession(). Save (entity);' all'interno di questo metodo o dichiarare '@ Transactional' anche il metodo' add'. poiché chiama un altro metodo transazionale, devi annotare anche questo. prova questo e dimmi se funziona – Apostolos

risposta

6

Hai provato la rimozione il seguente proprietà:

Credo che Hibernate chiuderà la sessione troppo presto e causerà il tuo errore. Poiché utilizzi Spring TransactionManager, lascia che chiuda la sessione.

+0

Ho provato con questa soluzione ma ho mantenuto lo stesso – SpringLearner

+0

Ok, per favore aggiorna la configurazione di Spring nel tuo post perché dobbiamo vederlo. Nella mia risposta ho supposto che tu abbia definito correttamente il tuo TransactionManager come ha fatto @Rupesh nella sua risposta. Con la sua risposta e la mia, oltre a rimuovere l'annotazione '@ Transactional' in TestPlanDaoImpl che non è necessaria dovrebbe funzionare bene – Dalc

5

è necessario aggiungere seguente codice nel file XML di configurazione 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

Questa è la risposta corretta. –

3

È necessario rimuovere l'annotazione @Transactional dal metodo repository, utilizzare solo l'annotazione @Transactional sul metodo livello di servizio.

@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

Si prega di aggiungere alcuni punti altrimenti sembra un commento. – surajsn

2

Rimuovere @Traviazione transazionale dalla funzione e utilizzarlo a livello di classe.

1

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

Sarebbe utile se fosse possibile aggiungere un contesto, questo renderà la risposta più facile da capire. –

1

Questo accade quando si tenta di salvare le modifiche su un Business Object dopo una transazione è già finito.

Penso che dovresti dare un'occhiata a Spring Data JPA? Ha molto più da offrire rispetto a un DAO generico.