Я пытаюсь выполнить некоторую работу по чтению, вычислению и сохранению JPA в фоновом потоке, запущенном методом сервиса.Я делаю всю свою работу в одном методе @Transactional сервиса.Другой метод в этой службе запускает поток, который его обрабатывает.Однако, если я пытаюсь получить доступ к ленивым отношениям @oneToMany, даже если я делаю это сразу же после получения результатов в первый раз, я получаю LazyInitializationException - без сеанса.Как не может быть никакого сеанса?Я ПРОСТО ПОЛУЧИЛ РЕЗУЛЬТАТ ОДНОЙ ЛИНИИ ДО.
Пожалуйста, игнорируйте, что пул потоков здесь не используется.Этот код написан на Groovy, поэтому разработчикам, работающим только на Java, может быть сложно понять.
@Service
public class NotifierService {
public void startNewNotifierThread() {
stopNotifierThreadIfRunning()
log.info "Starting notifier thread"
notifierThread = new Thread({
while(!Thread.interrupted()) {
runNotifier()
Thread.sleep(10000)
}
if(Thread.interrupted()) {
log.info("Reached end of thread due to interrupt")
}
})
notifierThread.start()
}
@Transactional public void runNotifier() {
boolean isAlive0 = TransactionSynchronizationManager.isActualTransactionActive()
Session session = (Session) entityManager.getDelegate();
Collection<User> allSubscribedUsers = userRepository.getAllSubscribedUsers()
log.debug "Processing subscriptions for ${allSubscribedUsers.size()} subscribed users"
int fcmMsgsSent = 0, apnMsgsSent = 0
boolean isAlive1 = TransactionSynchronizationManager.isActualTransactionActive()
allSubscribedUsers.each { User user ->
boolean isAlive2 = TransactionSynchronizationManager.isActualTransactionActive()
log.debug "Subscriptions for user ${user.email}: ${user.analysisSubscriptions.size()}"
Set<AnalysisSubscription> updatedSubscriptions = new HashSet<AnalysisSubscription>()
user.analysisSubscriptions.each { AnalysisSubscription subscription ->
boolean isAlive3 = TransactionSynchronizationManager.isActualTransactionActive()
int numResults = subscription.analysisResults.size() //LAZYINITIALIZATIONEXCEPTION
}
}
}
Результатом этого кода является isAlive0, isAlive1, isAlive2, isAlive3 - все false.Значение session.closed равно true даже в начале метода, который не имеет смысла, почему он может извлечь всех подписанных пользователей (если я использую репозиторий внизу - что заставляет меня подозревать, что метод использует свой собственный сеанс ...)?).Кажется, что @Transactional не работает: он должен ОТКРЫТЬ сеанс гибернации и ПРОДОЛЖИТЬ ОТКРЫТЬ до конца метода.Кажется, он даже не открывает сессию.