2016-11-08 19 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

相关问题