Skip to content

Commit 2ba5933

Browse files
committed
Order detector for AbstractDataSourceInitializers
Previously, the detector for AbstractDataSourceInitializers used the default detector order. This resulted in the initializers detected initializers running before Flyway. Constrastingly, the detector for DataSourceScriptDatabaseInitializers uses a custom order so its detected initializers would run after Flyway. This commit aligns the order of the detector for AbstractDataSourceInitializers with the order of the detector for DataSourceScriptDatabaseInitializers. This ensures that script-based initialization runs in the same order with respect to Flyway, irrespective of which initializer implementation is driving it. Fixes gh-28079
1 parent 90a5e34 commit 2ba5933

File tree

2 files changed

+34
-6
lines changed

2 files changed

+34
-6
lines changed

spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/integration/IntegrationAutoConfigurationTests.java

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,10 @@
2121
import io.rsocket.transport.ClientTransport;
2222
import io.rsocket.transport.netty.client.TcpClientTransport;
2323
import org.junit.jupiter.api.Test;
24-
import reactor.core.publisher.Mono;
2524

2625
import org.springframework.beans.DirectFieldAccessor;
2726
import org.springframework.boot.autoconfigure.AutoConfigurations;
27+
import org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration;
2828
import org.springframework.boot.autoconfigure.integration.IntegrationAutoConfiguration.IntegrationComponentScanConfiguration;
2929
import org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration;
3030
import org.springframework.boot.autoconfigure.jdbc.EmbeddedDataSourceConfiguration;
@@ -44,10 +44,8 @@
4444
import org.springframework.integration.annotation.MessagingGateway;
4545
import org.springframework.integration.config.IntegrationManagementConfigurer;
4646
import org.springframework.integration.context.IntegrationContextUtils;
47-
import org.springframework.integration.core.MessageSource;
4847
import org.springframework.integration.endpoint.MessageProcessorMessageSource;
4948
import org.springframework.integration.gateway.RequestReplyExchanger;
50-
import org.springframework.integration.handler.MessageProcessor;
5149
import org.springframework.integration.rsocket.ClientRSocketConnector;
5250
import org.springframework.integration.rsocket.IntegrationRSocketEndpoint;
5351
import org.springframework.integration.rsocket.ServerRSocketConnector;
@@ -166,6 +164,27 @@ void integrationJdbcDataSourceInitializerEnabled() {
166164
});
167165
}
168166

167+
@Test
168+
void whenIntegrationJdbcDataSourceInitializerIsEnabledThenFlywayCanBeUsed() {
169+
this.contextRunner.withUserConfiguration(EmbeddedDataSourceConfiguration.class)
170+
.withConfiguration(AutoConfigurations.of(DataSourceTransactionManagerAutoConfiguration.class,
171+
JdbcTemplateAutoConfiguration.class, IntegrationAutoConfiguration.class,
172+
FlywayAutoConfiguration.class))
173+
.withPropertyValues("spring.datasource.generate-unique-name=true",
174+
"spring.integration.jdbc.initialize-schema=always")
175+
.run((context) -> {
176+
IntegrationProperties properties = context.getBean(IntegrationProperties.class);
177+
assertThat(properties.getJdbc().getInitializeSchema())
178+
.isEqualTo(DataSourceInitializationMode.ALWAYS);
179+
JdbcOperations jdbc = context.getBean(JdbcOperations.class);
180+
assertThat(jdbc.queryForList("select * from INT_MESSAGE")).isEmpty();
181+
assertThat(jdbc.queryForList("select * from INT_GROUP_TO_MESSAGE")).isEmpty();
182+
assertThat(jdbc.queryForList("select * from INT_MESSAGE_GROUP")).isEmpty();
183+
assertThat(jdbc.queryForList("select * from INT_LOCK")).isEmpty();
184+
assertThat(jdbc.queryForList("select * from INT_CHANNEL_MESSAGE")).isEmpty();
185+
});
186+
}
187+
169188
@Test
170189
void integrationJdbcDataSourceInitializerDisabled() {
171190
this.contextRunner.withUserConfiguration(EmbeddedDataSourceConfiguration.class)
@@ -362,8 +381,9 @@ interface TestGateway extends RequestReplyExchanger {
362381
static class MessageSourceConfiguration {
363382

364383
@Bean
365-
MessageSource<?> myMessageSource() {
366-
return new MessageProcessorMessageSource(mock(MessageProcessor.class));
384+
org.springframework.integration.core.MessageSource<?> myMessageSource() {
385+
return new MessageProcessorMessageSource(
386+
mock(org.springframework.integration.handler.MessageProcessor.class));
367387
}
368388

369389
}
@@ -376,7 +396,7 @@ IntegrationRSocketEndpoint mockIntegrationRSocketEndpoint() {
376396
return new IntegrationRSocketEndpoint() {
377397

378398
@Override
379-
public Mono<Void> handleMessage(Message<?> message) {
399+
public reactor.core.publisher.Mono<Void> handleMessage(Message<?> message) {
380400
return null;
381401
}
382402

spring-boot-project/spring-boot/src/main/java/org/springframework/boot/jdbc/AbstractDataSourceInitializerDatabaseInitializerDetector.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121

2222
import org.springframework.boot.sql.init.dependency.AbstractBeansOfTypeDatabaseInitializerDetector;
2323
import org.springframework.boot.sql.init.dependency.DatabaseInitializerDetector;
24+
import org.springframework.core.Ordered;
2425

2526
/**
2627
* A {@link DatabaseInitializerDetector} for {@link AbstractDataSourceInitializer}.
@@ -29,9 +30,16 @@
2930
*/
3031
class AbstractDataSourceInitializerDatabaseInitializerDetector extends AbstractBeansOfTypeDatabaseInitializerDetector {
3132

33+
private static final int PRECEDENCE = Ordered.LOWEST_PRECEDENCE - 100;
34+
3235
@Override
3336
protected Set<Class<?>> getDatabaseInitializerBeanTypes() {
3437
return Collections.singleton(AbstractDataSourceInitializer.class);
3538
}
3639

40+
@Override
41+
public int getOrder() {
42+
return PRECEDENCE;
43+
}
44+
3745
}

0 commit comments

Comments
 (0)