2014-03-05 36 views
3

MyDao類有通過Hibernate SessionFactory完成整個持久性任務的方法,它工作正常。@PostConstruct中沒有會話休眠

我注入MyDao在爲MyService如上面看到的,但是當@PostConstruct init()方法被調用注入MyDao後(調試,我可以看到MyDao以及注入)獲得下一個休眠例外:

組織。 hibernate.HibernateException:沒有找到當前線程的會話

我的服務實現。

@Service("myService") 
@Transactional(readOnly = true) 
public class MyServiceImpl implements MyService { 

    @Autowired 
    private MyDao myDao; 
    private CacheList cacheList; 

    @PostConstruct 
    public void init() { 

     this.cacheList = new CacheList(); 
     this.cacheList.reloadCache(this.myDao.getAllFromServer()); 
    } 

    ... 
} 

的方式來解決

由於@瑜珈上面推薦給我,我已經使用TransactionTemplate的得到一個有效的/活動的事務會議,在這種情況下,我已經實現了throught構造和對我來說工作得很好。

@Service("myService") 
@Transactional(readOnly = true) 
public class MyServiceImpl implements MyService { 

    @Autowired 
    private MyDao myDao; 
    private CacheList cacheList; 

    @Autowired 
    public void MyServiceImpl(PlatformTransactionManager transactionManager) { 

     this.cacheList = (CacheList) new TransactionTemplate(transactionManager).execute(new TransactionCallback(){ 

      @Override 
      public Object doInTransaction(TransactionStatus transactionStatus) { 

       CacheList cacheList = new CacheList(); 
       cacheList.reloadCache(MyServiceImpl.this.myDao.getAllFromServer()); 

       return cacheList; 
      } 

     }); 
    } 

    ... 
} 
+0

你的代碼有一個'void',我不希望有一個:'public void MyServiceImpl'。如果這是一個構造函數,或者這是從別的地方調用的方法嗎? –

回答

4

我不認爲方法有允許在@PostConstruct水平,從而@Transactional不會做太大的,除非mode是任何交易設置爲aspectj<tx:annotation-driven mode="aspectj" />

this討論您可以使用TransactionTemplate啓動內部init()手動事務綁定session但如果要嚴格遵守聲明性事務,你需要使用ApplicationListener註冊事件和用戶ContextRefreshedEvent發起交易。

+0

非常感謝,TransactionTemplate對我來說工作得很好。 ;) – Dani

0

確保您在交易下運行。我可以看到交易註釋,但看起來像你錯過了,通過在春天使用<tx:annotation-driven/>標籤使用註釋激活交易管理。

0

發生這種情況是因爲MyServiceImpl.init()被Spring調用後MyServiceImpl相關的Bean構造和@Transaction註釋未用於管理會話生命週期。
一個解決方案可能是考慮Spring AOP的周圍使用緩存而不是@PostConstruct