我有一个emailsenderservice来异步管理电子邮件通知。 异步方法有2种,一种方法有效,但另一种方法会抛出LazyInitializationException:
@Service
public class EmailSenderService {
// working
@Async
public void sendNewBidRequestEmail(BidRequest bidRequest) {
this.sendNewBidRequestEmailToSupplier(bidRequest);
}
@Transactional
public void sendNewBidRequestEmailToSupplier(BidRequest bidRequest) {
sendNewBidRequestEmailToSupplier(bidRequest, bidRequest.getHotels());
}
@Transactional
public void sendNewBidRequestEmailToSupplier(BidRequest bidRequest, List<Hotel> hotelList) {
for (Hotel hotel : hotelList) {
...
this.sender.send()
}
}
// not working, throw exception
@Async
public void sendCancelledBidRequestEmail(BidRequest bidRequest, String reason) {
this.sendCancelledBidRequestEmailToSupplier(bidRequest, bidRequest.getHotels(), reason);
}
@Transactional
public void sendCancelledBidRequestEmailToSupplier(BidRequest bidRequest, List<Hotel> hotelList, String reason) {
for (Hotel hotel : hotelList) { // throw exception here
...
this.sender.send();
}
}
我完全关注this thread。
您可以看到两种异步方法的结构几乎相同。异步方法调用事务方法。但是第二个抛出org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: com.corpobids.server.entity.BidRequest.hotels, could not initialize proxy - no Session
。
我什至模仿第一个异步方法结构,将第二个方法修改为:
@Async
public void sendCancelledBidRequestEmail(BidRequest bidRequest, String reason) {
this.sendCancelledBidRequestEmailToSupplier(bidRequest, reason);
}
@Transactional
public void sendCancelledBidRequestEmailToSupplier(BidRequest bidRequest, String reason) {
this.sendCancelledBidRequestEmailToSupplier(bidRequest, bidRequest.getHotels(), reason);
}
@Transactional
public void sendCancelledBidRequestEmailToSupplier(BidRequest bidRequest, List<Hotel> hotelList, String reason) {
for (Hotel hotel : hotelList) { // exception in this line
...
this.sender.send();
}
}
}
这次,它给了我java.lang.IllegalStateException: org.hibernate.resource.jdbc.internal.LogicalConnectionManagedImpl@fce9b7b is closed
。
我想知道代码中的缺失点,希望能对您有所帮助。
答案 0 :(得分:1)
您在使用JPA时遇到问题。
在JPA中,关系OneToMany具有两种行为LAZY和EAGER。
您可以在以下位置查看正确的解释:Difference between FetchType LAZY and EAGER in Java Persistence API?
我假设在异步模式下调用代码时,JPA的上下文是松散的。由于上下文不同,因此Hibernate无法填充执行新查询的关系。为了解决您的问题,您有两种选择:
延迟加载的更好铅技术:
https://www.thoughts-on-java.org/5-ways-to-initialize-lazy-relations-and-when-to-use-them/