Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Multithreading Spring调度程序启动的任务线程_Multithreading_Spring_Hibernate_Jpa - Fatal编程技术网

Multithreading Spring调度程序启动的任务线程

Multithreading Spring调度程序启动的任务线程,multithreading,spring,hibernate,jpa,Multithreading,Spring,Hibernate,Jpa,我们正在构建一个包含数据层、业务层、服务层。。。 它还有一个调度器,每5秒钟唤醒一次,并在数据库表中查找任务,如果有任务要执行,则会启动一个线程来执行该任务。 问题在于,在执行过程中,任务需要从数据层读取和更新实体,其中一些实体具有延迟加载,并且当它因延迟加载异常而崩溃时,会话会在时间之前关闭 ERROR: org.springframework.scheduling.support.TaskUtils$LoggingErrorHandler - Unexpected error occ

我们正在构建一个包含数据层、业务层、服务层。。。 它还有一个调度器,每5秒钟唤醒一次,并在数据库表中查找任务,如果有任务要执行,则会启动一个线程来执行该任务。 问题在于,在执行过程中,任务需要从数据层读取和更新实体,其中一些实体具有延迟加载,并且当它因延迟加载异常而崩溃时,会话会在时间之前关闭

    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)
我们认为我们的问题更多的是架构上的,而不是技术上的

编辑1: 来自@radai评论

InitialAlignment有一个名为defenses的属性,它在 定义为lazy的列表属性,并使用以下内容进行注释 @OneToManyfetch=FetchType.LAZY 数据库访问层使用hibernate。该层打开一个hibernate会话,获取一个实体,并在会话结束后关闭hibernate会话
我不能肯定这一点,但以下是我认为发生在你身上的事情:

您有某种使用hibernate的数据库访问层。该层打开一个hibernate会话,获取一个实体,并在会话结束后关闭hibernate会话 您的代码调用此层以获取InitialAlignment的实例 InitialAlignment有一个名为defenses的属性,它迭代一些定义为lazy的列表属性,并用@OneToManyfetch=FetchType.lazy之类的注释,这意味着它在使用之前不会从数据库中获取。但是,只能在创建InitialAlignment实例的hibernate会话仍处于活动状态时获取惰性属性。 您的task TaskMatch在单独的线程中运行,并被赋予此实体,它尝试访问lazy字段,但创建该对象的hibernate会话已关闭,因此hibernate无法返回数据库并获取列表,这就是您遇到的异常 最快的解决方案是更改列表字段上@OneToMany hibernate注释的fetch属性。

尝试将@Transactional添加到计划方法中。这将为当前任务执行创建会话


祝你好运

你是对的,这就是问题所在。出于性能原因,我们希望保持延迟加载,而不使用即时获取。我们已经尝试应用事务注释,但是会话的范围没有到达线程。还有其他建议吗?谢谢在您的数据访问层中添加一个特殊的方法—类似于getAlignmentWithDefenses,它将返回一个完整的实体—通过使用HQL select from Alignment join fetch defenses或获取一个对齐并调用getDefenses,然后返回它。获取任务的对象时使用此方法。如果这是您唯一的用途,那么您最好去让fetch变得急切……但它不会是获取实体的相同TX