[spring-projects/spring-boot]Spring 不尊重 application.properties 中的 jpa 引导模式

2024-05-09 188 views
9

自 spring boot 2.4.1 以来,spring.data.jpa.repositories.bootstrap-mode 已恢复为默认值。我想启用 spring.data.jpa.repositories.bootstrap-mode=deferred 但它被忽略(日志显示默认)

但是,如果我不设置 application.propety,而是使用 @EnableJpaRepositories("com.rebirthCorp.rebirth.repositories", bootstrapMode = BootstrapMode.DEFERRED) 设置它,则可以正确启用它。注意:这可能会帮助您找到错误的根本原因: Multiple Spring Data modules found, entering strict repository configuration mode!

@SpringBootApplication
@EnableIntegration
@EnableJpaRepositories("com.rebirthCorp.rebirth.repositories", bootstrapMode = BootstrapMode.DEFERRED)
@EnableElasticsearchRepositories("com.rebirthCorp.rebirth.elasticrepositories")
class RebirthApplication

回答

9

我们有一个 Data JPA 冒烟测试,它使用配置的延迟模式application.properties并应用该配置:

2021-01-21 08:30:48.624  INFO 71765 --- [           main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFERRED mode.

从上面我可以看到,您的应用程序正在使用多个 Spring Data 模块,除此之外,我不清楚它与配置设置有效的应用程序有何不同。为了避免我们在尝试重现问题时不得不猜测这些差异,请花一些时间提供一个完整但最小的重现问题的示例。这将使我们能够确定我们正在解决与您相同的问题。您可以通过将示例推送到 GitHub 上的单独存储库或将其压缩并附加到此问题来与我们共享示例。

7

这也适用于类路径上的多个 Spring Data 模块:

2021-01-22 12:02:37.522  INFO 56986 --- [           main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode!
2021-01-22 12:02:37.524  INFO 56986 --- [           main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data Elasticsearch repositories in DEFAULT mode.
2021-01-22 12:02:37.531  INFO 56986 --- [           main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 4 ms. Found 0 Elasticsearch repository interfaces.
2021-01-22 12:02:37.535  INFO 56986 --- [           main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode!
2021-01-22 12:02:37.536  INFO 56986 --- [           main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data Reactive Elasticsearch repositories in DEFAULT mode.
2021-01-22 12:02:37.537  INFO 56986 --- [           main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 0 ms. Found 0 Reactive Elasticsearch repository interfaces.
2021-01-22 12:02:37.546  INFO 56986 --- [           main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode!
2021-01-22 12:02:37.547  INFO 56986 --- [           main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFERRED mode.
2021-01-22 12:02:37.553  INFO 56986 --- [           main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 1 ms. Found 0 JPA repository interfaces.
7

如果您希望我们查看此问题,请提供所需的信息。如果在接下来的 7 天内未提供信息,此问题将被关闭。

4

我想我也有类似的问题。如果我在生产配置中使用 @EnableJpaRepositories 注释(注释本身没有设置 bootStrap 模式)并在测试 application.properties 中设置 spring.data.jpa.repositories.bootstrap-mode ,则属性中的值将被忽略并使用 DEFAULT 。

有时我必须使用 EnableJpaRepositories 只是为了配置搜索存储库的位置。但是,我没有在注释中设置 bootStrap,因为我想使用系统范围内配置的默认值(在环境/application.properties 中)。我希望在生产中使用 DEFAULT 模式初始化存储库,但在测试中我希望延迟初始化存储库,因此我将其设置在测试文件夹中的 application.properties 中。这不起作用,因为 AnnotationRepositoryConfigurationSource.getBootstrapMode 不考虑 application.properties 中的引导模式以及硬编码 BootstrapMode.DEFAULT 的回退。

我附上概念验证项目来重现此案例。

换句话说,EnableJpaRepositories 注释中的 DEFAULT 模式(即使未显式声明)比 application.properties 中设置的 bootstrap-mode 具有更高的优先级。

如果这种行为是通过设计实现的,您能否提供惯用的方式来设置一切?

演示.zip

0

换句话说,EnableJpaRepositories 注释中的 DEFAULT 模式(即使未显式声明)比 application.properties 中设置的 bootstrap-mode 具有更高的优先级。

这是设计使然。如果你使用的话,@EnableJpaRepositories你就是在告诉 Spring Boot 的自动配置停止,并表明你想自己控制一切。

如果这种行为是通过设计实现的,您能否提供惯用的方式来设置一切?

您应该bootstrapMode在 上使用该属性@EnableJpaRepositories

6

这是设计使然。如果你使用的话,@EnableJpaRepositories你就是在告诉 Spring Boot 的自动配置停止,并表明你想自己控制一切。

在我的示例中,我将与 JPA 相关的类打包到主应用程序包之外。所以我需要以某种方式扫描存储库接口。这就是我使用@EnableJpaRepositories.还有其他方法可以告诉 spring 包列表来扫描存储库吗?

您应该bootstrapMode在 上使用该属性@EnableJpaRepositories

好的,那么我该如何使用相同的@EnableJpaRepositories注释为生产配置 DEFAULT bootstrapMode 并为测试配置 LAZY 模式?

我现在看到的唯一方法是为生产和测试配置文件创建不同的配置,如下所示:

@Configuration
@EnableJpaRepositories(bootstrapMode = DEFAULT, basePackageClasses = TestRepository.class)
@Profile("prod")
class ProdConfig {}

@Configuration
@EnableJpaRepositories(bootstrapMode = LAZY, basePackageClasses = TestRepository.class)
@Profile("test")
class TestConfig {}

但这对我来说似乎很奇怪。如果我可以使用单一配置会更容易:

@Configuration
@EnableJpaRepositories(basePackageClasses = TestRepository.class)
class ProdConfig {}

通过根本不显式声明 bootstrapMode,但可以从环境/application.properties 设置 bootstrapMode。这种行为是否会破坏某些我没有看到的情况?我无意以任何方式推动,只是想了解如何以最惯用的方式解决此案。

8

同时,对于遇到此问题的任何人,我有一个解决方法来解决我的问题。我最初的目标是让所有存储库 bean 在测试中变得懒惰。因此,我创建了仅在测试中运行的小型 BeanFactoryPostProcessor 并使所有存储库类变得惰性:

@Component
public class LazyRepositoryBFPP implements BeanFactoryPostProcessor {
  @Override
  public void postProcessBeanFactory(ConfigurableListableBeanFactory factory) throws BeansException {
    for(var name : factory.getBeanNamesForType(Repository.class)) {
      factory.getBeanDefinition(name).setLazyInit(true);
    }
  }
}
6

还有其他方法可以告诉 spring 包列表来扫描存储库吗?

文档中所述,您可以用于@EntityScan此目的。

@kolychev 如果您还有任何其他问题,请在 Stack Overflow 或 Gitter 上提问。您的情况与@LifeIsStrange 不同,因此这里不适合讨论。我们也更喜欢将问题纯粹保留为错误和增强功能。

6

如果您希望我们查看此问题,请提供所需的信息。如果在接下来的 7 天内未提供信息,此问题将被关闭。

8

由于缺乏所需的反馈而关闭。如果您希望我们查看此问题,请提供所需的信息,我们将重新打开该问题。

0

我有同样的问题。
关键是,如果您使用@EnableJpaRepositories注释,那么 Spring Boot 自动配置将被禁用。
我需要使用注释来配置repositoryBaseClass。如果使用注释,则 的值bootstrapMode将设置为并且不考虑BootstrapMode.DEFAULT该值。spring.data.jpa.repositories.bootstrap-mode

我不得不做这样的事情:

@Configuration
public class DataConfig {
  private static final String REPOSITORY_PACKAGE = "org.eu.rubensa.repository";

  @Value("${spring.data.jpa.repositories.bootstrap-mode:default}")
  public static String SPRING_DATA_JPA_REPOSITORIES_BOOTSTRAP_MODE;

  @Configuration
  @ConditionalOnExpression("'${SPRING_DATA_JPA_REPOSITORIES_BOOTSTRAP_MODE}' == 'default'")
  @EnableJpaRepositories(basePackages = {
      REPOSITORY_PACKAGE }, repositoryBaseClass = CustomJpaRepository.class, bootstrapMode = BootstrapMode.DEFAULT)
  public static class DefaultJpaRepositoriesConfig {
  }

  @Configuration
  @ConditionalOnExpression("'${SPRING_DATA_JPA_REPOSITORIES_BOOTSTRAP_MODE}' == 'deferred'")
  @EnableJpaRepositories(basePackages = {
      REPOSITORY_PACKAGE }, repositoryBaseClass = CustomJpaRepository.class, bootstrapMode = BootstrapMode.DEFERRED)
  public static class DeferredJpaRepositoriesConfig {
  }

  @Configuration
  @ConditionalOnExpression("'${SPRING_DATA_JPA_REPOSITORIES_BOOTSTRAP_MODE}' == 'lazy'")
  @EnableJpaRepositories(basePackages = {
      REPOSITORY_PACKAGE }, repositoryBaseClass = CustomJpaRepository.class, bootstrapMode = BootstrapMode.LAZY)
  public static class LazyJpaRepositoriesConfig {
  }

}
2

@rubensa您可以使用@EntityScan而不是@EnableJpaRepositories配置基础包。

5

@wilkinsona我可以指定repositoryBaseClass(这就是使用的原因@EnableJpaRepository)吗@EntityScan anotation?我不这么认为...:(

6

不幸的是没有,没有。这是特定于商店的,所以我认为@EntityScan不是合适的地方。也就是说,如果我们可以提供一些其他机制来做到这一点,这样您就不需要使用@EnableJpaRepositories.如果您希望我们探讨这一点,请打开一个新问题。

5

我有同样的问题。更愿意通过属性进行配置,而不是更改 @EnableJpaConfiguration 注释中的模式。