我们正在构建一个具有数据层,业务层,服务层的系统...... 它还有一个Scheduler,它每5秒唤醒一次并在DataBase Table中查找Tasks,如果有要执行的Task,则启动一个线程来执行该Task。 问题是,在执行过程中,任务需要从数据层读取和更新实体,其中一些实体具有延迟加载,当它与LazyLoading异常崩溃时,会话在时间之前关闭。
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评论)
答案 0 :(得分:2)
我无法确定这一点,但这就是我认为发生在你身上的事情:
InitialAlignment
InitialAlignment
有一个名为defenses
的属性,它迭代一些定义为lazy的List
属性(用@OneToMany(fetch = FetchType.LAZY)
注释),这意味着它不是从数据库直到使用。但是只有在创建InitialAlignment
实例的hibernate会话仍处于活动状态时才能获取延迟属性。TaskMatch
),在一个单独的线程中运行并且已经被赋予此实体,尝试访问惰性字段,但是创建该对象的hibernate会话已经关闭,因此hibernate无法返回到数据库并获取你的列表,这就是你得到的例外最快的解决方案是在列表字段中更改@OneToMany hibernate注释的fetch
属性。
答案 1 :(得分:0)
尝试将@Transactional
添加到您安排的方法中。这应该为当前任务执行创建一个会话。