传递给另一个线程的 Spring Boot JPA 存储库不起作用

拉吉·马尔霍特拉

我有一个自动装配的 jpa 存储库对象正在工作。但是,我需要使用它从多个线程向数据库中添加行。
但是,在将其传递给另一个线程后,它失败了。代码结构

@SpringBootApplication(exclude = HealthcheckConfig.class)
public class Application implements CommandLineRunner {

    @Autowired
    private DBRepository dbRepository;

    @Autowired
    private AppConfig appConfig;

    private ExecutorService executors = Executors.newFixedThreadPool(3);

    Application() {
    }

    @Override
    public void run(final String... args) {

        final DBSchemaObject temp = new Application("testdb", "testfield");
        dbRepository.save(temp); // This WORKs!!!
       
        for (FileStatus fileStatus: fileStatuses) {
            executors.execute(new ThreadSafeClass(dbRepository));
        }
    }

    public static void main(final String[] args) {
        new SpringApplicationBuilder(Application.class)
                .web(WebApplicationType.NONE)
                .run(args)
                .close();
    }
}

但是,从线程安全类执行 dbRepository.save() 时,出现错误原因: java.lang.IllegalStateException: org.springframework.context.annotation.AnnotationConfigApplicationContext@41330d4f has been closed already

详细留言: Error creating bean with name 'spring.datasource-org.springframework.boot.autoconfigure.jdbc.DataSourceProperties': Could not bind properties to 'DataSourceProperties' : prefix=spring.datasource, ignoreInvalidFields=false, ignoreUnknownFields=true

堆栈跟踪:

{StackTraceElement@14839} "org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:800)"
{StackTraceElement@14840} "org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:229)"
{StackTraceElement@14841} "org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1354)"
{StackTraceElement@14842} "org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1204)"
{StackTraceElement@14843} "org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:564)"
{StackTraceElement@14844} "org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:524)"
{StackTraceElement@14845} "org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335)"
{StackTraceElement@14846} "org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234)"
{StackTraceElement@14847} "org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333)"
{StackTraceElement@14848} "org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208)"
{StackTraceElement@14849} "org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:410)"
{StackTraceElement@14850} "org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1334)"
{StackTraceElement@14851} "org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1177)"
{StackTraceElement@14852} "org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:564)"
{StackTraceElement@14853} "org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:524)"
{StackTraceElement@14854} "org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335)"
{StackTraceElement@14855} "org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234)"
{StackTraceElement@14856} "org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333)"
{StackTraceElement@14857} "org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208)"
{StackTraceElement@14858} "org.springframework.beans.factory.support.DefaultListableBeanFactory$1.orderedStream(DefaultListableBeanFactory.java:481)"
{StackTraceElement@14859} "org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.detectPersistenceExceptionTranslators(PersistenceExceptionTranslationInterceptor.java:167)"
{StackTraceElement@14860} "org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:149)"
{StackTraceElement@14861} "org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)"
{StackTraceElement@14862} "org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor$CrudMethodMetadataPopulatingMethodInterceptor.invoke(CrudMethodMetadataPostProcessor.java:174)"
{StackTraceElement@14863} "org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)"
{StackTraceElement@14864} "org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:97)"
{StackTraceElement@14865} "org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)"
{StackTraceElement@14866} "org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:215)"
{StackTraceElement@14867} "com.sun.proxy.$Proxy99.save(Unknown Source)"
{StackTraceElement@14868} "com.xxxx.run(Application.java:109)"
{StackTraceElement@14869} "java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)"
{StackTraceElement@14870} "java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)"
{StackTraceElement@14871} "java.lang.Thread.run(Thread.java:748)"

如何跨多个线程使用 spring boot 存储库对象?

斯维特林·扎列夫

问题是您的run()方法只是安排要执行的任务,而不是等待它们完成。这是正在发生的事情:

  1. new SpringApplicationBuilder(Application.class) 您正在使用命令行运行程序创建新的应用程序上下文 Application
  2. .run(args)然后初始化并执行应用程序上下文的run()方法
  3. run()方法调度要执行的任务并立即存在:
 public void run(final String... args) {
        for (FileStatus fileStatus: fileStatuses) {
            executors.execute(new ThreadSafeClass(dbRepository));
        }
    }
  1. 由于已run()终止,spring 假定应用程序已完成并调用.close();从而关闭应用程序上下文并使其无法使用任何 spring 功能,例如存储库。

  2. 计划任务被执行,但上下文已经关闭,因此它们失败并抛出异常。

解决方案是在退出 run 方法之前等待任务完成。由于您的示例太少,这只是一个示例。或者,您可以使用其他方法等待任务完成,例如CountDownLatch等,而无需关闭线程池:

for (FileStatus fileStatus: fileStatuses) {
    executors.execute(new ThreadSafeClass(dbRepository));
}
executors.shutdown(); // prevents the executor from accepting any new tasks
executors.awaitTermination(); // wait for the tasks to finish

ExecutorService::shutdown javadoc

ExecutorService::awaitTermination javadoc

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

OneToMany + Spring Boot + Jpa不起作用

Spring Boot JPA不起作用

Spring JPA存储库删除方法不起作用

Spring JPA对存储库的数据扫描不起作用

@Query在Spring Boot(JPA)+ Azure Cosmos数据库中不起作用

悲观锁不起作用Spring Boot Data JPA

动态查询不起作用Spring Boot JPA

Spring Boot和JPA事务不起作用

事务注释在使用JPA的Spring Boot中不起作用

fething ID不起作用后的Spring Boot JPA更新

NullPointer异常存储库Spring Boot Jpa

Spring Boot JPA存储库错误

Spring Annotation @WebMvcTest在具有Jpa存储库的应用程序中不起作用

Spring Data JPA存储库:派生查询中的IN子句不起作用

Spring Boot存储库保存不起作用(仅显示选择)

Spring Boot和Swagger 2:UnsatisfiedDependencyException-存储库测试不起作用

Spring Boot和Spring Data JPA的批量插入不起作用

测试 Spring JPA 存储库(非 Spring Boot)

一对多映射不起作用Spring数据JPA

使用 Spring Boot 和 JPA 更新密码不起作用

Hibernate JPA @OneToOne双向在Spring-Boot中不起作用

Spring Boot / JPA:带引号的保留字列名称不起作用

运行 Spring Boot 应用程序后发现 0 个 JPA 存储库接口

当来自另一个事务的具有延迟加载的 Hibernate 对象被传递给方法时,Spring @Transactional 不起作用

Spring Boot 测试:JPA 存储库返回不一致的数据

Spring Boot + Jpa:如何使此查找方法起作用?

在 spring boot jpa 存储库中保留嵌入(相关)项目?

如何在Spring Boot的JPA存储库中编写查询?

Spring Boot JPA,存储库不删除记录