2014-10-28 2 views
0

Мы строим систему с уровнем данных, бизнес-слоем, уровнем обслуживания ... У этого также есть Планировщик, который просыпается каждые 5 секунд и ищет Задачи в таблице DataBase, если есть Задачи для выполнения, поток запускается для выполнения этой задачи. Проблема заключается в том, что в ходе выполнения задача должна считывать и обновлять объекты с уровня данных, некоторые из этих объектов имеют ленивую загрузку, а также когда она выходит из строя с помощью исключения LazyLoading, сессия закрывается до времени.Темы задач, запущенные Spring Scheduler

ERROR: org.springframework.scheduling.support.TaskUtils$LoggingErrorHandler - Unexpected error occurred in scheduled task. 
org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: com.soft1.pack1.data.entity.InitialAlignment.initialAlignment, could not initialize proxy - no Session 
    at org.hibernate.collection.internal.AbstractPersistentCollection.throwLazyInitializationException(AbstractPersistentCollection.java:566) 
    at org.hibernate.collection.internal.AbstractPersistentCollection.withTemporarySessionIfNeeded(AbstractPersistentCollection.java:186) 
    at org.hibernate.collection.internal.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:545) 
    at org.hibernate.collection.internal.AbstractPersistentCollection.read(AbstractPersistentCollection.java:124) 
    at org.hibernate.collection.internal.PersistentBag.iterator(PersistentBag.java:266) 
    at com.soft1.pack1.data.entity.InitialAlignment.getDefenses(InitialAlignment.java:80) 
    at com.soft1.pack1.data.entity.TaskMatch.run(TaskMatch.java:74) 
    at com.soft1.pack1.negocio.TaskTaskExecutor.TaskTaskExecutorMethod(TaskTaskExecutor.java:61) 
    at sun.reflect.GeneratedMethodAccessor40.invoke(Unknown Source) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
    at java.lang.reflect.Method.invoke(Method.java:606) 
    at org.springframework.scheduling.support.ScheduledMethodRunnable.run(ScheduledMethodRunnable.java:65) 
    at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54) 
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471) 
    at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:304) 
    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$301(ScheduledThreadPoolExecutor.java:178) 
    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:293) 
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) 
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) 
    at java.lang.Thread.run(Thread.java:745) 

Мы считаем, что наша проблема более архитектурна, чем техническая.

Любая помощь будет полезна.

Спасибо.

EDIT1: (от @radai комментариев)

  1. InitialAlignment имеет свойство защиты, которая перебирает над список свойств то будет определен как ленивый (аннотированный с чем-то вроде @OneToMany (скачивает = FetchType.LAZY))
  2. Уровень доступа к базе данных использует спящий режим. этот слой открывает перед гибернации сеанс, получает юридическое лицо, и закрывает гибернации сессию после того, как сам по себе

ответ

1

я не могу быть уверен в этом, но вот что я думаю случилось с вами:

  1. вы имеют некоторый уровень доступа к базе данных, который использует спящий режим. этот слой открывает гибернации сеанс, получает юридическое лицо, и закрывает гибернации сессию после того, как сам по себе
  2. код вызывает в этот слой, чтобы получить экземпляр InitialAlignment
  3. InitialAlignment имеет свойство defenses, что итерация по некоторым List собственности который определен как ленивый (аннотированный с чем-то вроде @OneToMany(fetch = FetchType.LAZY)), что означает, что он не извлекается из базы данных до тех пор, пока не будет использован. но ленивые свойства могут быть получены только в том случае, когда сеанс hibernate, который создал экземпляр InitialAlignment, все еще жив.
  4. Ваша задача (TaskMatch), которая запускается в отдельном потоке и была предоставлена ​​этому объекту, пытается получить доступ к ленивому полю, но сеанс hibernate, который создал объект, уже закрыт, поэтому спящий режим не может вернуться в базу данных и принести свой список, и вот исключение Youre получая

самым быстрым решением было бы изменить fetch свойство вашего @OneToMany зимуют аннотацию на поле списка.

+0

Вы правы, это проблема. Мы хотим сохранить ленивую загрузку по соображениям производительности, а не использовать EAGER. Мы уже пробовали применить аннотацию Transactional, но область действия сессии не достигла нити. Любое другое предложение? Благодаря! – Hamlett

+0

добавьте специальный метод на вашем уровне доступа к данным - что-то вроде getAlignmentWithDefenses(), которое вернет «полный» объект - либо путем uaing HQL («выберите из выравнивания для выравнивания присоединения»), либо получив выравнивание и вызов getDefenses() и затем возвращая его. используйте этот метод при извлечении объектов для задач. если это ваше единственное использование, то вы могли бы пойти и сделать выборку нетерпеливо. – radai

0

Попробуйте добавить @Transactional к вашему планируемому методу. Это должно создать сеанс для выполнения текущей задачи.

Удачи вам!

+0

... но это не будет тот же TX, который доставил объект – radai

Смежные вопросы