java - 异步查询在 Spring Data JPA 项目中无法正常工作

标签 java jpa asynchronous spring-data spring-data-jpa

在学习完 @KevinBowersox 的针对 Java 开发人员的 Spring Data 无限技能类(class)后,唯一似乎没有像宣传的那样工作的部分是异步方法。请注意,在类(class)开始时,他介绍了 xml 和 Java 配置,但他在类(class)的其余部分中继续使用 xml 配置,而我在每个练习中都继续使用 Java 配置,并且能够获得所有其他部分工作。一个细微的差别是我使用的是 IntelliJ IDEA,而不是他在整个类(class)中使用的 STS。

如果任何熟悉 Spring Data 异步查询或其类(class)部分 (https://www.safaribooksonline.com/library/view/spring-data-for/9781771375924/video241705.html) 的人对可能缺少的内容有一些见解,请告诉我。

以下是相关部分:

/* Application.java */

@EnableAsync
public class Application {

public static void main(String[] args) throws ParseException {

    try (AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(
            DataConfiguration.class)) {
        BookRepository repository = context.getBean(BookRepository.class);

        // TODO: Make method Async
        for (long x = 0; x < 4; x++) {
            repository.findByIds(x);
        }
    }
}

}

/* BaseRepository.java */

@NoRepositoryBean
public interface BaseRepository<T, ID extends Serializable> extends JpaRepository<T, ID> {

    @Override
    @Async("executor")
    List<T> findByIds(ID... ids);
}

/* ExtendedRepositoryImpl.java */

public class ExtendedRepositoryImpl<T, ID extends Serializable>
        extends SimpleJpaRepository<T, ID> implements BaseRepository<T, ID> {
    private JpaEntityInformation<T, ?> entityInformation;
    private final EntityManager entityManager;

    public ExtendedRepositoryImpl(
            JpaEntityInformation<T, ?> entityInformation,
            EntityManager entityManager) {
        super(entityInformation, entityManager);
        this.entityInformation = entityInformation;
        this.entityManager = entityManager;
    }

    @Override
    public List<T> findByIds(ID... ids) {
        Query query = this.entityManager.createQuery("select e from " + this.entityInformation.getEntityName()
        + " e where e." + this.entityInformation.getIdAttribute().getName() + " in :ids");
        query.setParameter("ids", Arrays.asList(ids));

        long wait = new Random().nextInt(10000-1) +1;
        System.out.println(wait);

        try {
            Thread.sleep(wait);
        }
        catch (InterruptedException e) {
            e.printStackTrace();
        }

        System.out.println("Executing query for ID: " + Arrays.toString(ids));

        return (List<T>) query.getResultList();
    }
}

/* DataConfiguration.java(又名 AppConfig.java)*/

@EnableJpaRepositories(
            basePackages = {"com.infiniteskills.springdata.async"},
            repositoryBaseClass = com.infiniteskills.springdata.async.data.repository.ExtendedRepositoryImpl.class,
            repositoryImplementationPostfix = "CustomImpl")
    @EnableJpaAuditing(auditorAwareRef = "customAuditorAware")
    @EnableAsync
    @EnableTransactionManagement
    @ComponentScan("com.infiniteskills.springdata.async")
    @Configuration
    public class DataConfiguration implements AsyncConfigurer {
        @Bean
        public CustomAuditorAware customAuditorAware() {
            return new CustomAuditorAware();
        }

        @Bean
        public DataSource dataSource() {
            EmbeddedDatabaseBuilder builder = new EmbeddedDatabaseBuilder();
            return builder.setType(EmbeddedDatabaseType.H2).build();
        }

        @Bean
        public EntityManagerFactory entityManagerFactory() {
            HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
            // Generate tables in database
            vendorAdapter.setGenerateDdl(true);

            Properties jpaProperties = new Properties();
            jpaProperties.put("hibernate.hbm2ddl.auto", "create-drop");
            //jpaProperties.put("hibernate.dialect", "org.hibernate.dialect.HSQLDialect");
            //jpaProperties.put("hibernate.connection.driver_class", "org.h2.Driver");

            // After DDL has been run, run init script to populate table with data.
            jpaProperties.put("hibernate.hbm2ddl.import_files", "init.sql");

            // Entity Manager Factory Bean
            LocalContainerEntityManagerFactoryBean entityManagerFactoryBean = new LocalContainerEntityManagerFactoryBean();
            entityManagerFactoryBean.setDataSource(dataSource());
            entityManagerFactoryBean.setPackagesToScan("com.infiniteskills.springdata.async");
            entityManagerFactoryBean.setJpaVendorAdapter(vendorAdapter);
            entityManagerFactoryBean.setJpaProperties(jpaProperties);
            entityManagerFactoryBean.afterPropertiesSet();
            return entityManagerFactoryBean.getObject();
        }

        @Bean
        public PlatformTransactionManager transactionManager() {
            JpaTransactionManager transactionManager = new JpaTransactionManager();
            transactionManager.setEntityManagerFactory(entityManagerFactory());
            return transactionManager;
        }

        @Override
        @Bean(name = "executor")
        public Executor getAsyncExecutor() {
            ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
            executor.setCorePoolSize(10);
            executor.setMaxPoolSize(10);
            executor.setQueueCapacity(100);
            executor.setThreadNamePrefix("executor-");
            executor.initialize();
            return executor;
        }

        @Override
        @Bean
        public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
            return new SimpleAsyncUncaughtExceptionHandler();
        }
    }

最佳答案

该方法必须具有返回类型 voidFuture 才能异步调用。

您可以在此处的文档中阅读它:https://docs.spring.io/spring/docs/current/spring-framework-reference/html/scheduling.html#scheduling-annotation-support-async

关于java - 异步查询在 Spring Data JPA 项目中无法正常工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45203808/

相关文章:

java - Spring Integration - Microsoft SQL Server 2012 的消息存储配置

java - 更改集 [liquibasefile] 失败。错误: Table [table name] doesn't exist [Failed SQL: INSERT INTO [table name] (name) VALUES ('ROLE_USER' )]

java - 非主键列的一对一关系

java - 如何计算 Java 类在运行时的反汇编?

Python - 对象MagicMock不能在 'await'表达式中使用

javascript - 从单个服务调用返回多个“独立”异步结果的正确 Angular 模式是什么

java - java中finally子句中的return语句有危险吗?

java - JNativehook 不捕获密码

java - 如何在没有数据冗余的情况下与JPA实体建立递归关系?

node.js - 尝试从 api 获取 token 时 Node 获取的错误行为