Skip to content

Commit

Permalink
Change default BootstrapMode for JPA repositories
Browse files Browse the repository at this point in the history
Change the default `BootstrapMode` for auto-configured `JpaRepositories`
to `BootstrapMode.DEFERRED` to allow the initialization of
`EntityManagerFactory` to be parallelized for increased startup efficiency.

Prior to this change, the default BootstrapMode for all auto-configured
Spring Data repositories was `BootstrapMode.DEFAULT`.

Closes gh-16230
  • Loading branch information
scottfrederick authored and philwebb committed Jan 22, 2020
1 parent ae3bdc7 commit 2888896
Show file tree
Hide file tree
Showing 6 changed files with 54 additions and 16 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2012-2019 the original author or authors.
* Copyright 2012-2020 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -56,6 +56,7 @@
*
* @author Phillip Webb
* @author Josh Long
* @author Scott Frederick
* @since 1.0.0
* @see EnableJpaRepositories
*/
Expand Down Expand Up @@ -95,7 +96,7 @@ private static final class BootstrapExecutorCondition extends AnyNestedCondition
}

@ConditionalOnProperty(prefix = "spring.data.jpa.repositories", name = "bootstrap-mode",
havingValue = "deferred", matchIfMissing = false)
havingValue = "deferred", matchIfMissing = true)
static class DeferredBootstrapMode {

}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2012-2019 the original author or authors.
* Copyright 2012-2020 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -34,6 +34,7 @@
*
* @author Phillip Webb
* @author Dave Syer
* @author Scott Frederick
*/
class JpaRepositoriesRegistrar extends AbstractRepositoryConfigurationSourceSupport {

Expand All @@ -56,7 +57,7 @@ protected RepositoryConfigurationExtension getRepositoryConfigurationExtension()

@Override
protected BootstrapMode getBootstrapMode() {
return (this.bootstrapMode == null) ? super.getBootstrapMode() : this.bootstrapMode;
return (this.bootstrapMode == null) ? BootstrapMode.DEFERRED : this.bootstrapMode;
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2012-2019 the original author or authors.
* Copyright 2012-2020 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -51,6 +51,7 @@
*
* @author Dave Syer
* @author Oliver Gierke
* @author Scott Frederick
*/
class JpaRepositoriesAutoConfigurationTests {

Expand Down Expand Up @@ -85,7 +86,7 @@ void autoConfigurationShouldNotKickInEvenIfManualConfigDidNotCreateAnyRepositori
}

@Test
void whenBootstrappingModeIsLazyWithMultipleAsyncExecutorBootstrapExecutorIsConfigured() {
void whenBootstrapModeIsLazyWithMultipleAsyncExecutorBootstrapExecutorIsConfigured() {
this.contextRunner.withUserConfiguration(MultipleAsyncTaskExecutorConfiguration.class)
.withConfiguration(AutoConfigurations.of(TaskExecutionAutoConfiguration.class,
TaskSchedulingAutoConfiguration.class))
Expand All @@ -96,7 +97,7 @@ void whenBootstrappingModeIsLazyWithMultipleAsyncExecutorBootstrapExecutorIsConf
}

@Test
void whenBootstrappingModeIsLazyWithSingleAsyncExecutorBootstrapExecutorIsConfigured() {
void whenBootstrapModeIsLazyWithSingleAsyncExecutorBootstrapExecutorIsConfigured() {
this.contextRunner.withUserConfiguration(SingleAsyncTaskExecutorConfiguration.class)
.withPropertyValues("spring.data.jpa.repositories.bootstrap-mode=lazy")
.run((context) -> assertThat(
Expand All @@ -105,7 +106,7 @@ void whenBootstrappingModeIsLazyWithSingleAsyncExecutorBootstrapExecutorIsConfig
}

@Test
void whenBootstrappingModeIsDeferredBootstrapExecutorIsConfigured() {
void whenBootstrapModeIsDeferredBootstrapExecutorIsConfigured() {
this.contextRunner.withUserConfiguration(MultipleAsyncTaskExecutorConfiguration.class)
.withConfiguration(AutoConfigurations.of(TaskExecutionAutoConfiguration.class,
TaskSchedulingAutoConfiguration.class))
Expand All @@ -116,14 +117,24 @@ void whenBootstrappingModeIsDeferredBootstrapExecutorIsConfigured() {
}

@Test
void whenBootstrappingModeIsDefaultBootstrapExecutorIsNotConfigured() {
void whenBootstrapModeIsDefaultBootstrapExecutorIsNotConfigured() {
this.contextRunner.withUserConfiguration(MultipleAsyncTaskExecutorConfiguration.class)
.withConfiguration(AutoConfigurations.of(TaskExecutionAutoConfiguration.class,
TaskSchedulingAutoConfiguration.class))
.withPropertyValues("spring.data.jpa.repositories.bootstrap-mode=default").run((context) -> assertThat(
context.getBean(LocalContainerEntityManagerFactoryBean.class).getBootstrapExecutor()).isNull());
}

@Test
void bootstrapModeIsDeferredByDefault() {
this.contextRunner.withUserConfiguration(MultipleAsyncTaskExecutorConfiguration.class)
.withConfiguration(AutoConfigurations.of(TaskExecutionAutoConfiguration.class,
TaskSchedulingAutoConfiguration.class))
.run((context) -> assertThat(
context.getBean(LocalContainerEntityManagerFactoryBean.class).getBootstrapExecutor())
.isEqualTo(context.getBean("applicationTaskExecutor")));
}

@Configuration(proxyBeanMethods = false)
@EnableScheduling
@Import(TestConfiguration.class)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2012-2019 the original author or authors.
* Copyright 2012-2020 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -36,6 +36,7 @@
import org.springframework.context.annotation.ComponentScan.Filter;
import org.springframework.core.annotation.AliasFor;
import org.springframework.core.env.Environment;
import org.springframework.data.repository.config.BootstrapMode;
import org.springframework.test.context.BootstrapWith;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import org.springframework.transaction.annotation.Transactional;
Expand All @@ -62,6 +63,7 @@
*
* @author Phillip Webb
* @author Artsiom Yudovin
* @author Scott Frederick
* @since 1.4.0
* @see AutoConfigureDataJpa
* @see AutoConfigureTestDatabase
Expand Down Expand Up @@ -99,6 +101,14 @@
@PropertyMapping("spring.jpa.show-sql")
boolean showSql() default true;

/**
* The {@link BootstrapMode} for the test repository support. Defaults to
* {@link BootstrapMode#LAZY}.
* @return the {@link BootstrapMode} to use for test the repository
*/
@PropertyMapping("spring.data.jpa.repositories.bootstrap-mode")
BootstrapMode bootstrapMode() default BootstrapMode.LAZY;

/**
* Determines if default filtering should be used with
* {@link SpringBootApplication @SpringBootApplication}. By default no beans are
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2012-2019 the original author or authors.
* Copyright 2012-2020 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -20,17 +20,18 @@

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.data.repository.config.BootstrapMode;

import static org.assertj.core.api.Assertions.assertThat;

/**
* Tests for the {@link DataJpaTest#properties properties} attribute of
* {@link DataJpaTest @DataJpaTest}.
* Tests for non-default attributes of {@link DataJpaTest @DataJpaTest}.
*
* @author Artsiom Yudovin
* @author Scott Frederick
*/
@DataJpaTest(properties = "spring.profiles.active=test")
class DataJpaTestPropertiesIntegrationTests {
@DataJpaTest(properties = "spring.profiles.active=test", bootstrapMode = BootstrapMode.DEFERRED)
class DataJpaTestAttributesIntegrationTests {

@Autowired
private Environment environment;
Expand All @@ -40,4 +41,10 @@ void environmentWithNewProfile() {
assertThat(this.environment.getActiveProfiles()).containsExactly("test");
}

@Test
void bootstrapModeIsSet() {
assertThat(this.environment.getProperty("spring.data.jpa.repositories.bootstrap-mode"))
.isEqualTo(BootstrapMode.DEFERRED.name());
}

}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2012-2019 the original author or authors.
* Copyright 2012-2020 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -25,6 +25,7 @@
import org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration;
import org.springframework.boot.autoconfigure.liquibase.LiquibaseAutoConfiguration;
import org.springframework.context.ApplicationContext;
import org.springframework.data.repository.config.BootstrapMode;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.test.context.TestPropertySource;

Expand All @@ -37,6 +38,7 @@
*
* @author Phillip Webb
* @author Andy Wilkinson
* @author Scott Frederick
*/
@DataJpaTest
@TestPropertySource(properties = "spring.jpa.hibernate.use-new-id-generator-mappings=false")
Expand Down Expand Up @@ -106,4 +108,10 @@ void liquibaseAutoConfigurationWasImported() {
assertThat(this.applicationContext).has(importedAutoConfiguration(LiquibaseAutoConfiguration.class));
}

@Test
void bootstrapModeIsLazyByDefault() {
assertThat(this.applicationContext.getEnvironment().getProperty("spring.data.jpa.repositories.bootstrap-mode"))
.isEqualTo(BootstrapMode.LAZY.name());
}

}

0 comments on commit 2888896

Please sign in to comment.