Stop JPA and a custom Flyway bean from causing a startup failure

Previously, if an application used JPA and declared its own Flyway bean,
startup would fail. The custom Flyway bean would switch off
auto-configuration of the FlywayMigrationInitializer bean but the
context’s entity manager factory beans would still be configured to
depend on the migration initialiser.

This commit splits the post-processor that configures the dependencies
into two. One that configures the dependency on the Flyway bean and
one that configures the dependency on the FlywayMigrationInitializer
bean. When to auto-configuration of the FlywayMigrationInitializer is
switched off, the auto-configuration of the latter dependency is also
switched off.

Closes gh-4079
pull/4095/head
Andy Wilkinson 9 years ago
parent 81f6a77d15
commit fd53cbf2f3

@ -35,7 +35,6 @@ import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.core.io.DefaultResourceLoader; import org.springframework.core.io.DefaultResourceLoader;
import org.springframework.core.io.ResourceLoader; import org.springframework.core.io.ResourceLoader;
import org.springframework.orm.jpa.AbstractEntityManagerFactoryBean; import org.springframework.orm.jpa.AbstractEntityManagerFactoryBean;
@ -60,7 +59,6 @@ public class FlywayAutoConfiguration {
@Configuration @Configuration
@ConditionalOnMissingBean(Flyway.class) @ConditionalOnMissingBean(Flyway.class)
@EnableConfigurationProperties(FlywayProperties.class) @EnableConfigurationProperties(FlywayProperties.class)
@Import(FlywayJpaDependencyConfiguration.class)
public static class FlywayConfiguration { public static class FlywayConfiguration {
@Autowired @Autowired
@ -122,6 +120,21 @@ public class FlywayAutoConfiguration {
@ConditionalOnMissingBean @ConditionalOnMissingBean
public FlywayMigrationInitializer flywayInitializer(Flyway flyway) { public FlywayMigrationInitializer flywayInitializer(Flyway flyway) {
return new FlywayMigrationInitializer(flyway, this.migrationStrategy); return new FlywayMigrationInitializer(flyway, this.migrationStrategy);
}
/**
* Additional configuration to ensure that {@link EntityManagerFactory} beans
* depend-on the {@code flywayInitializer} bean.
*/
@Configuration
@ConditionalOnClass(LocalContainerEntityManagerFactoryBean.class)
@ConditionalOnBean(AbstractEntityManagerFactoryBean.class)
protected class FlywayInitializerJpaDependencyConfiguration extends
EntityManagerFactoryDependsOnPostProcessor {
public FlywayInitializerJpaDependencyConfiguration() {
super("flywayInitializer");
}
} }
@ -129,7 +142,7 @@ public class FlywayAutoConfiguration {
/** /**
* Additional configuration to ensure that {@link EntityManagerFactory} beans * Additional configuration to ensure that {@link EntityManagerFactory} beans
* depend-on the flyway bean. * depend-on the {@code flyway} bean.
*/ */
@Configuration @Configuration
@ConditionalOnClass(LocalContainerEntityManagerFactoryBean.class) @ConditionalOnClass(LocalContainerEntityManagerFactoryBean.class)
@ -138,7 +151,7 @@ public class FlywayAutoConfiguration {
EntityManagerFactoryDependsOnPostProcessor { EntityManagerFactoryDependsOnPostProcessor {
public FlywayJpaDependencyConfiguration() { public FlywayJpaDependencyConfiguration() {
super("flywayInitializer", "flyway"); super("flyway");
} }
} }

@ -17,6 +17,7 @@
package org.springframework.boot.autoconfigure.flyway; package org.springframework.boot.autoconfigure.flyway;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections;
import javax.sql.DataSource; import javax.sql.DataSource;
@ -27,14 +28,18 @@ import org.junit.Rule;
import org.junit.Test; import org.junit.Test;
import org.junit.rules.ExpectedException; import org.junit.rules.ExpectedException;
import org.springframework.beans.factory.BeanCreationException; import org.springframework.beans.factory.BeanCreationException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.PropertyPlaceholderAutoConfiguration; import org.springframework.boot.autoconfigure.PropertyPlaceholderAutoConfiguration;
import org.springframework.boot.autoconfigure.jdbc.DataSourceBuilder; import org.springframework.boot.autoconfigure.jdbc.DataSourceBuilder;
import org.springframework.boot.autoconfigure.jdbc.EmbeddedDataSourceConfiguration; import org.springframework.boot.autoconfigure.jdbc.EmbeddedDataSourceConfiguration;
import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder;
import org.springframework.boot.test.EnvironmentTestUtils; import org.springframework.boot.test.EnvironmentTestUtils;
import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.core.Ordered; import org.springframework.core.Ordered;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.equalTo;
@ -47,6 +52,7 @@ import static org.junit.Assert.assertThat;
* *
* @author Dave Syer * @author Dave Syer
* @author Phillip Webb * @author Phillip Webb
* @author Andy Wilkinson
*/ */
public class FlywayAutoConfigurationTests { public class FlywayAutoConfigurationTests {
@ -171,7 +177,13 @@ public class FlywayAutoConfigurationTests {
FlywayMigrationInitializer initializer = this.context FlywayMigrationInitializer initializer = this.context
.getBean(FlywayMigrationInitializer.class); .getBean(FlywayMigrationInitializer.class);
assertThat(initializer.getOrder(), equalTo(Ordered.HIGHEST_PRECEDENCE)); assertThat(initializer.getOrder(), equalTo(Ordered.HIGHEST_PRECEDENCE));
}
@Test
public void customFlywayWithJpa() throws Exception {
registerAndRefresh(CustomFlywayWithJpaConfiguration.class,
EmbeddedDataSourceConfiguration.class, FlywayAutoConfiguration.class,
PropertyPlaceholderAutoConfiguration.class);
} }
private void registerAndRefresh(Class<?>... annotatedClasses) { private void registerAndRefresh(Class<?>... annotatedClasses) {
@ -204,6 +216,25 @@ public class FlywayAutoConfigurationTests {
} }
} }
@Configuration
protected static class CustomFlywayWithJpaConfiguration {
@Autowired
private DataSource dataSource;
@Bean
public Flyway flyway() {
return new Flyway();
}
@Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactoryBean() {
return new EntityManagerFactoryBuilder(new HibernateJpaVendorAdapter(),
Collections.emptyMap(), null).dataSource(this.dataSource).build();
}
}
@Component @Component
protected static class MockFlywayMigrationStrategy implements FlywayMigrationStrategy { protected static class MockFlywayMigrationStrategy implements FlywayMigrationStrategy {

Loading…
Cancel
Save