2016-11-08 70 views
0

我有一個SpringBoot應用程序使用SpringData來保存Oracle數據庫上的數據,並使用spring-boot-starter-activemq來處理JMS隊列。如何將Hibernate會話關聯到JmsListener方法

我在公開一個DELETE Rest WebService,這需要一段時間。而且我不希望我的用戶掛在回覆中。

因此我添加了一個註釋爲@JmsListener的方法,它可以完成這項工作,我用jmsTemplate.convertAndSend()來調用它。

但如果我的治療findAll()部分作品完美,只要我試圖訪問數據(只是顯示它爲例)與findAll()方法我面對我的懶惰集合LazyLoadingException檢索,說我沒有休眠會話。 org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: ..., could not initialize proxy - no Session

這裏是我的代碼片段是否有幫助:

public void myMethod(int batchSize) { 
    // Send a JMS message with a POJO 
    LOGGER.trace("Calling JMS method..."); 
    final JmsTemplate jmsTemplate = context.getBean(JmsTemplate.class); 
    jmsTemplate.convertAndSend("runJob", batchSize); 
} 

@JmsListener(destination = "runJob") 
private void runJob(final int batchSize) { 
    LOGGER.debug("Calling runJob with batchSize {}", batchSize); 
    List<MyEntity> myEntities = myRepository.findAll(); 
    LOGGER.debug("{} entities retrieved from the DB", myEntities.size()); // Prints the actual number of entities in my DB 
    for(Entity entity : entities){ 
     LOGGER.debug("Entity name {}", entity.getName()); // Prints entity name 
     LOGGER.debug("Entity first collection's value {}", entity.getMyList().get(0).toString()); // org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: ..., could not initialize proxy - no Session 
    } 
} 

// ----------------------- 
// Full code of my repository -> The implementation is generated by spring-data http://docs.spring.io/spring-data/jpa/docs/current/reference/html/#jpa.query-methods.query-creation 
public interface MyRepository extends org.springframework.data.jpa.repository.JpaRepository<MyEntity, Long>{} 

我只是想知道如何讓我的會話連接到我的Jms方法。

乾杯, 奧利維爾

+2

不要描述你的代碼和你的例外。發佈它們。 –

+0

@JBNizet剛剛添加了一段代碼片段。順便說一句,這個異常在我的初始文章(懶惰集合中的LazyLoadingException)中列出,代碼(顯示數據)也在那裏。我雖然可以專注於真正重要的東西:問題而不是純粹的代碼。任何方式,在這裏。 – Olivier

回答

1

JmsListener方法異步處理(這就是爲什麼你在做這個整點),所以它在不同的線程運行。如果它運行在不同的線程上,則不能使用相同的事務。

你可以,但是,啓動一個新交易時,將處理的JMS消息,但你必須認識到這是什麼意思具體。在runJob上添加@Transactional應該這樣做。因爲它現在是異步的,所以你必須在響應中考慮到這一點。你將返回什麼HTTP狀態碼。例如,背景可能會失敗。

+0

感謝您的回覆。我同意100%關於異步流程的目標。當然,我沒有試圖讓'runJob'和'myMethod'運行在同一個事務中,當然。我只是想'runJob'在調用'myRepository.findAll()'後不關閉Hibernate會話。我忘了提到它,但是,我試圖讓'runJob'' @ Transactional',但沒有成功。像你一樣,雖然它會這樣做...而且我不明白如果一個方法在運行時關閉它的'session',怎麼會是'@ Transactional' ... 順便說一句,我還有幾個代碼人們可以知道JMS方法已經做了什麼。 – Olivier

+0

你的方法是私人的,它必須是公開的,以便它代表交易目的。我真的很驚訝私人作品'@ JmsListener' –

+0

對不起,但它不能解決問題。我確信它會......但我仍然面臨着完全相同的問題,而我所有的方法都是「公開」的。 – Olivier

相關問題