@EnableJpaRepositories注释禁用数据.sql初始化脚本



我的基于 Spring Boot (v2.3.4) 的应用程序使用包含核心实体和业务逻辑的自定义库。要使用这个库中的实体和存储库,我必须使用@EnableJpaRepositories@EntityScan注释,并提供适当的包。

我还想在应用程序启动期间使用一些必需的数据(假设配置)初始化数据库。我发现 Spring Boot 允许使用data.sqldata-${platform}.sql文件来实现这一点。

长话短说,使用@EnableJpaRepositories注释时,不会执行data.sql脚本。

我在代码中做了一些挖掘,发现当不使用@EnableJpaRepositories注释时entityManagerFactorybean 是org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean类型。此 Bean 使用org.springframework.boot.autoconfigure.orm.jpa.DataSourceInitializedPublisherBean 后处理器,该处理器触发org.springframework.boot.autoconfigure.jdbc.DataSourceSchemaCreatedEvent事件,指示模式已创建。侦听此事件的类是org.springframework.boot.autoconfigure.jdbc.DataSourceInitializerInvoker。此侦听器从类调用initSchema()org.springframework.boot.autoconfigure.jdbc.DataSourceInitializer方法。此方法负责使用脚本进行整个初始化data.sql

看起来设置@EnableJpaRepositories注释会为entityManagerFactorybean 创建不同类的实例,这不支持这种简单的初始化。

我的基本问题是如何使它都与@EnableJpaRepositories注释一起工作。我总是可以使用Hibernate的import.sql文件(工作正常),但我也试图了解引擎盖下到底发生了什么,我该如何控制它。

更新 128.09.2021

我做了进一步的调查,@EnableJpaRepositories注释不会更改entityManagerFactory的实例类型,但它在创建 Bean 时(在创建 Bean 期间)会导致静默异常 (?org.springframework.context.annotation.internalAsyncAnnotationProcessororg.springframework.scheduling.annotation.ProxyAsyncConfiguration)。看起来一切都与@EnableAsync注释有关,我也在使用注释,但不知道它可能相关。但它是 - 删除它使初始化工作,即使使用@EnableJpaRepositories.

更新 228.09.2021

我已经找到了我的问题的完整解释。必须满足 4 个条件才能重现问题:

  • 应用程序配置中的@EnableJpaRepositories注释
  • 应用程序配置中的@EnableAsync注释
  • 配置实现AsyncConfigurer接口
  • 自动连接任何JpaRepository存储库或任何其他注入存储库的 Bean

启用异步执行和实现AsyncConfigurer使得整个配置在常规 bean 之前实例化。因为 Spring 必须注入存储库,所以它也需要实例化entityManagerFactorybean。Spring 打印然后INFO级别日志,如下所示:

Bean 'entityManagerFactoryBuilder' of type [org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)

不符合资格BeanPostProcessors之一DataSourceInitializedPublisher负责触发DataSourceSchemaCreatedEvent事件。如果没有该事件,data-${platform}.sql脚本将根本不被处理。

我不确定@EnableJpaRepositories在这个过程中的作用是什么,但没有它,问题就不会发生。

重现问题的最少代码(data.sql位于src/main/resources):

@Entity
public FileStore {
...
}
public interface FileStoreRepository extends extends JpaRepository<FileStore, Long> {
}
@Configuration
@EnableAsync
@EnableJpaRepositories
public class Configuration implements AsyncConfigurer {
@Autowired
private FileStoreRepository fileStoreRepository;
...
}

解决 方案

我知道有两种解决方案:

  • AsyncConfigurer及其覆盖的方法和@EnableAsync注释一起移动到单独的配置类
  • 在自动连线的 bean 上使用@Lazy注释,如下所示:
@Lazy
@Autowired
private FileStoreRepository fileStoreRepository;

D. Ball@Allen也指出了类似的问题,可以在那里检查。

此行为已更改。

看看 操作指南。

加:

spring.jpa.defer-datasource-initialization: true

最新更新