为什么我不能在@async method中获取结果?(“illegalstateexception:引发entitymanagerfactory is closed“(entitymanagerfactory已关闭)”

slwdgvem  于 2021-07-24  发布在  Java
关注(0)|答案(1)|浏览(293)

我正在尝试编写一个简单的spring引导程序并练习@async。我想把你的所有记录都取出来 teacher 实体异步。
我的数据库访问对象:

public interface TeacherService {
    List<Teacher> findAll(Pageable pageable);
}

如何实施:

public class TeacherServiceImpl implements TeacherService{

        @Autowired
        private TeacherRepository repository;

        @Override
        public List<Teacher> findAll(Pageable pageable) {
            Page<Teacher> page =  repository.findAll(pageable);
            return page.get().collect(Collectors.toList());
        }
}

我的异步方法:

@Component
public class PrintAllTeacherDataBaseResult {
    @Autowired
    TeacherService teacher;

    @Async
    public AsyncResult<List<Teacher>> printPage(Pageable page){
        return new AsyncResult<>(teacher.findAll(page));
    }
}

当我打电话的时候 printPage 方法没有 @Async 很好用。但当我使用它时,会抛出以下异常:

java.lang.IllegalStateException: Failed to execute CommandLineRunner
    at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:807) [spring-boot-2.4.2.jar:2.4.2]
    at org.springframework.boot.SpringApplication.callRunners(SpringApplication.java:788) [spring-boot-2.4.2.jar:2.4.2]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:333) [spring-boot-2.4.2.jar:2.4.2]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1311) [spring-boot-2.4.2.jar:2.4.2]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1300) [spring-boot-2.4.2.jar:2.4.2]
    at com.hatef.demo.DemoApplication.main(DemoApplication.java:97) [classes/:na]
Caused by: java.lang.ClassCastException: org.springframework.util.concurrent.ListenableFutureTask cannot be cast to org.springframework.scheduling.annotation.AsyncResult
    at async.PrintAllTeacherDataBaseResult$$EnhancerBySpringCGLIB$$ccbb6656.printPage(<generated>) ~[classes/:na]
    at com.hatef.demo.DemoApplication.run(DemoApplication.java:103) [classes/:na]
    at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:804) [spring-boot-2.4.2.jar:2.4.2]
    ... 5 common frames omitted

    java.lang.IllegalStateException: EntityManagerFactory is closed
    at org.hibernate.internal.SessionFactoryImpl.validateNotClosed(SessionFactoryImpl.java:513) ~[hibernate-core-5.4.27.Final.jar:5.4.27.Final]
    at org.hibernate.internal.SessionFactoryImpl.getMetamodel(SessionFactoryImpl.java:660) ~[hibernate-core-5.4.27.Final.jar:5.4.27.Final]
    at org.hibernate.hql.internal.ast.util.SessionFactoryHelper.findEntityPersisterByName(SessionFactoryHelper.java:141) ~[hibernate-core-5.4.27.Final.jar:5.4.27.Final]
    at org.hibernate.hql.internal.ast.util.SessionFactoryHelper.requireClassPersister(SessionFactoryHelper.java:167) ~[hibernate-core-5.4.27.Final.jar:5.4.27.Final]
    at org.hibernate.hql.internal.ast.tree.FromElementFactory.addFromElement(FromElementFactory.java:91) ~[hibernate-core-5.4.27.Final.jar:5.4.27.Final]
    at org.hibernate.hql.internal.ast.tree.FromClause.addFromElement(FromClause.java:77) ~[hibernate-core-5.4.27.Final.jar:5.4.27.Final]
    at org.hibernate.hql.internal.ast.HqlSqlWalker.createFromElement(HqlSqlWalker.java:333) ~[hibernate-core-5.4.27.Final.jar:5.4.27.Final]
    at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.fromElement(HqlSqlBaseWalker.java:3758) ~[hibernate-core-5.4.27.Final.jar:5.4.27.Final]
    at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.fromElementList(HqlSqlBaseWalker.java:3647) ~[hibernate-core-5.4.27.Final.jar:5.4.27.Final]
    at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.fromClause(HqlSqlBaseWalker.java:732) ~[hibernate-core-5.4.27.Final.jar:5.4.27.Final]
    at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.query(HqlSqlBaseWalker.java:588) ~[hibernate-core-5.4.27.Final.jar:5.4.27.Final]
    at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.selectStatement(HqlSqlBaseWalker.java:325) ~[hibernate-core-5.4.27.Final.jar:5.4.27.Final]
    at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.statement(HqlSqlBaseWalker.java:273) ~[hibernate-core-5.4.27.Final.jar:5.4.27.Final]
    at org.hibernate.hql.internal.ast.QueryTranslatorImpl.analyze(QueryTranslatorImpl.java:276) ~[hibernate-core-5.4.27.Final.jar:5.4.27.Final]
    at org.hibernate.hql.internal.ast.QueryTranslatorImpl.doCompile(QueryTranslatorImpl.java:192) ~[hibernate-core-5.4.27.Final.jar:5.4.27.Final]
    at org.hibernate.hql.internal.ast.QueryTranslatorImpl.compile(QueryTranslatorImpl.java:144) ~[hibernate-core-5.4.27.Final.jar:5.4.27.Final]
    at org.hibernate.engine.query.spi.HQLQueryPlan.<init>(HQLQueryPlan.java:113) ~[hibernate-core-5.4.27.Final.jar:5.4.27.Final]
    at org.hibernate.engine.query.spi.HQLQueryPlan.<init>(HQLQueryPlan.java:73) ~[hibernate-core-5.4.27.Final.jar:5.4.27.Final]
    at org.hibernate.engine.query.spi.QueryPlanCache.getHQLQueryPlan(QueryPlanCache.java:162) ~[hibernate-core-5.4.27.Final.jar:5.4.27.Final]
    at org.hibernate.internal.AbstractSharedSessionContract.getQueryPlan(AbstractSharedSessionContract.java:604) ~[hibernate-core-5.4.27.Final.jar:5.4.27.Final]
    at org.hibernate.internal.AbstractSharedSessionContract.createQuery(AbstractSharedSessionContract.java:716) ~[hibernate-core-5.4.27.Final.jar:5.4.27.Final]
    at org.hibernate.internal.AbstractSharedSessionContract.createQuery(AbstractSharedSessionContract.java:779) ~[hibernate-core-5.4.27.Final.jar:5.4.27.Final]
    at org.hibernate.query.criteria.internal.CriteriaQueryImpl$1.buildCompiledQuery(CriteriaQueryImpl.java:314) ~[hibernate-core-5.4.27.Final.jar:5.4.27.Final]
    at org.hibernate.query.criteria.internal.compile.CriteriaCompiler.compile(CriteriaCompiler.java:165) ~[hibernate-core-5.4.27.Final.jar:5.4.27.Final]
    at org.hibernate.internal.AbstractSharedSessionContract.createQuery(AbstractSharedSessionContract.java:742) ~[hibernate-core-5.4.27.Final.jar:5.4.27.Final]
    at org.hibernate.internal.AbstractSharedSessionContract.createQuery(AbstractSharedSessionContract.java:113) ~[hibernate-core-5.4.27.Final.jar:5.4.27.Final]
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_151]
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_151]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_151]
    at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_151]
    at org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.invoke(SharedEntityManagerCreator.java:311) ~[spring-orm-5.3.3.jar:5.3.3]
    at com.sun.proxy.$Proxy101.createQuery(Unknown Source) ~[na:na]
    at org.springframework.data.jpa.repository.support.SimpleJpaRepository.getQuery(SimpleJpaRepository.java:703) ~[spring-data-jpa-2.4.3.jar:2.4.3]
    at org.springframework.data.jpa.repository.support.SimpleJpaRepository.getQuery(SimpleJpaRepository.java:654) ~[spring-data-jpa-2.4.3.jar:2.4.3]
    at org.springframework.data.jpa.repository.support.SimpleJpaRepository.findAll(SimpleJpaRepository.java:444) ~[spring-data-jpa-2.4.3.jar:2.4.3]
    at org.springframework.data.jpa.repository.support.SimpleJpaRepository.findAll(SimpleJpaRepository.java:411) ~[spring-data-jpa-2.4.3.jar:2.4.3]
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_151]
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_151]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_151]
    at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_151]
    at org.springframework.data.repository.core.support.RepositoryMethodInvoker$RepositoryFragmentMethodInvoker.lambda$new$0(RepositoryMethodInvoker.java:289) ~[spring-data-commons-2.4.3.jar:2.4.3]
    at org.springframework.data.repository.core.support.RepositoryMethodInvoker.doInvoke(RepositoryMethodInvoker.java:137) ~[spring-data-commons-2.4.3.jar:2.4.3]
    at org.springframework.data.repository.core.support.RepositoryMethodInvoker.invoke(RepositoryMethodInvoker.java:121) ~[spring-data-commons-2.4.3.jar:2.4.3]
    at org.springframework.data.repository.core.support.RepositoryComposition$RepositoryFragments.invoke(RepositoryComposition.java:524) ~[spring-data-commons-2.4.3.jar:2.4.3]
    at org.springframework.data.repository.core.support.RepositoryComposition.invoke(RepositoryComposition.java:285) ~[spring-data-commons-2.4.3.jar:2.4.3]
    at org.springframework.data.repository.core.support.RepositoryFactorySupport$ImplementationMethodExecutionInterceptor.invoke(RepositoryFactorySupport.java:531) ~[spring-data-commons-2.4.3.jar:2.4.3]
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) [spring-aop-5.3.3.jar:5.3.3]
    at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.doInvoke(QueryExecutorMethodInterceptor.java:156) ~[spring-data-commons-2.4.3.jar:2.4.3]
    at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.invoke(QueryExecutorMethodInterceptor.java:131) ~[spring-data-commons-2.4.3.jar:2.4.3]
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) [spring-aop-5.3.3.jar:5.3.3]
    at org.springframework.data.projection.DefaultMethodInvokingMethodInterceptor.invoke(DefaultMethodInvokingMethodInterceptor.java:80) ~[spring-data-commons-2.4.3.jar:2.4.3]
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) [spring-aop-5.3.3.jar:5.3.3]
    at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:123) ~[spring-tx-5.3.3.jar:5.3.3]
    at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:388) ~[spring-tx-5.3.3.jar:5.3.3]
    at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:119) [spring-tx-5.3.3.jar:5.3.3]
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) [spring-aop-5.3.3.jar:5.3.3]
    at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:137) [spring-tx-5.3.3.jar:5.3.3]
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) [spring-aop-5.3.3.jar:5.3.3]
    at org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor$CrudMethodMetadataPopulatingMethodInterceptor.invoke(CrudMethodMetadataPostProcessor.java:174) [spring-data-jpa-2.4.3.jar:2.4.3]
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) [spring-aop-5.3.3.jar:5.3.3]
    at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:97) [spring-aop-5.3.3.jar:5.3.3]
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) [spring-aop-5.3.3.jar:5.3.3]
    at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:215) [spring-aop-5.3.3.jar:5.3.3]
    at com.sun.proxy.$Proxy105.findAll(Unknown Source) [na:na]
    at services.TeacherServiceImpl.findAll(TeacherServiceImpl.java:33) [classes/:na]
    at async.PrintAllTeacherDataBaseResult.printPage(PrintAllTeacherDataBaseResult.java:23) [classes/:na]
    at async.PrintAllTeacherDataBaseResult$$FastClassBySpringCGLIB$$ccfcfab4.invoke(<generated>) [classes/:na]
    at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218) [spring-core-5.3.3.jar:5.3.3]
    at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:779) [spring-aop-5.3.3.jar:5.3.3]
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163) [spring-aop-5.3.3.jar:5.3.3]
    at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:750) [spring-aop-5.3.3.jar:5.3.3]
    at org.springframework.aop.interceptor.AsyncExecutionInterceptor.lambda$invoke$0(AsyncExecutionInterceptor.java:115) [spring-aop-5.3.3.jar:5.3.3]
    at java.util.concurrent.FutureTask.run$$$capture(FutureTask.java:266) ~[na:1.8.0_151]
    at java.util.concurrent.FutureTask.run(FutureTask.java) ~[na:1.8.0_151]
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) ~[na:1.8.0_151]
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) ~[na:1.8.0_151]
    at java.lang.Thread.run(Thread.java:748) ~[na:1.8.0_151]

我怎么称呼它:

@Autowired
ApplicationContextProvider applicationContextProvider;

public static void main(String[] args) {
    SpringApplication.run(DemoApplication.class, args);
}

@Override
public void run(String...args) throws Exception {
    PrintAllTeacherDataBaseResult p = applicationContextProvider.getApplicationContext().getBean(PrintAllTeacherDataBaseResult.class);
    AsyncResult<List<Teacher>> a = p.printPage(PageRequest.of(0, 2));
    a.get().stream().forEach(System.out::println);
}

但我的问题是为什么会抛出异常。
更新
我不知道为什么,但我改变了 @EnableAsync@EnableAsync(mode = AdviceMode.ASPECTJ) 一切都成功了!但它不是新线程创建的
现在我的问题是为什么在使用 @EnableAsync 为什么它在 @EnableAsync(mode = AdviceMode.ASPECTJ) 更新
我可以通过将这些更改应用到我的代码中来解决我的问题:首先还原 @EnableAsync(mode = AdviceMode.ASPECTJ)@EnableAsync 然后:

public interface TeacherService {
    @Async
    Future<List<Teacher>> findAll(Pageable pageable);
}

以及如何实施:

public class TeacherServiceImpl implements TeacherService{

        @Autowired
        private TeacherRepository repository;

        @Override
        public Future<List<Teacher>> findAll(Pageable pageable) {
             Page<Teacher> page =  repository.findAll(pageable);
             return new AsyncResult<>(page.get().collect(Collectors.toList()));
    }
}

以及我如何运行上述方法:

@Autowired
ApplicationContextProvider applicationContextProvider;

public static void main(String[] args) {
    SpringApplication.run(DemoApplication.class, args);
}

@Override
public void run(String...args) throws Exception {
    PrintAllTeacherDataBaseResult p = applicationContextProvider.getApplicationContext().getBean(PrintAllTeacherDataBaseResult.class);
    Future<List<Teacher>> a = p.printPage(PageRequest.of(0, 2));
    a.get().forEach(System.out::println);
}

我很感激任何能澄清到底发生了什么的帮助。

b5buobof

b5buobof1#

你应该看看这篇文章https://www.baeldung.com/spring-async
首先,返回类型为的异步方法应该在将来进行 Package 。每次对feature对象调用get()时,您都会订阅结果,当前线程将等待计算结果。
upd:首先尝试为asyncexecutioninterceptor和async读取javadoc。

<p>In terms of target method signatures, any parameter types are supported.
However, the return type is constrained to either {@code void} or
{@link java.util.concurrent.Future}. In the latter case, you may declare the
more specific {@link org.springframework.util.concurrent.ListenableFuture} or
{@link java.util.concurrent.CompletableFuture} types which allow for richer
interaction with the asynchronous task and for immediate composition with
further processing steps.

它是一个api,你应该遵循它。在案例1中,您使用的是asyncresult。它不是允许的类型,但它继承自listenablefuture。
现在在asyncexecutionaspectsupport的这个方法中

@Nullable
protected Object doSubmit(Callable<Object> task, AsyncTaskExecutor executor, Class<?> returnType) {
    if (CompletableFuture.class.isAssignableFrom(returnType)) {
        return CompletableFuture.supplyAsync(() -> {
            try {
                return task.call();
            }
            catch (Throwable ex) {
                throw new CompletionException(ex);
            }
        }, executor);
    }
    else if (ListenableFuture.class.isAssignableFrom(returnType)) {
        return ((AsyncListenableTaskExecutor) executor).submitListenable(task);
    }
    else if (Future.class.isAssignableFrom(returnType)) {
        return executor.submit(task);
    }
    else {
        executor.submit(task);
        return null;
    }
}

您进入了第二个else语句,之后它提供了classcastexception(您可以对其进行更深入的调试)。
关于版本2:

Future<List<Teacher>> a = p.printPage(PageRequest.of(0, 2));

实际上你没有调用printpage,你只是创建了一个未来,一旦你开始执行它,它就会在里面调用它。它将在一个.get()上启动,执行将在单独的线程中启动(如果您配置了一个以上线程的线程执行器)。

相关问题