В соответствии с документацией по Flyway можно использовать Flyway в проекте Grails 3 за пределами -коробка:
Grails 3.x основан на Spring Boot и поставляется с готовой интеграцией для Flyway.
Все, что вам нужно сделать, это добавить flyway-core в ваш build.gradle:compile "org.flywaydb:flyway-core:4.1.1"
Spring Boot затем автоматически подключит Flyway к своему источнику данных и вызовет его при запуске.
Это не работает для меня. Flyway не срабатывает при запуске приложения. В логах вижу подозрительные строчки:
FlywayAutoConfiguration did not match - @ConditionalOnClass found required class 'org.flywaydb.core.Flyway' (OnClassCondition) - @ConditionalOnProperty (flyway.enabled) matched (OnPropertyCondition) - @ConditionalOnBean (types: javax.sql.DataSource; SearchStrategy: all) did not find any beans (OnBeanCondition) ... Exclusions: org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration
А вот как выглядит класс Spring FlywayAutoConfiguration:
@Configuration
@ConditionalOnClass(Flyway.class)
@ConditionalOnBean(DataSource.class)
@ConditionalOnProperty(prefix = "flyway", name = "enabled", matchIfMissing = true)
@AutoConfigureAfter({ DataSourceAutoConfiguration.class,
HibernateJpaAutoConfiguration.class })
public class FlywayAutoConfiguration {
Так что мне кажется, что это не работает, потому что DataSourceAutoConfiguration
исключен из автонастройки.
Верен ли этот анализ?
Почему и где исключено DataSourceAutoConfiguration
? Предположительно где-то глубоко внутри Grails, потому что я не знаю ни одного места в моем коде, которое могло бы вызвать это.
Как сделать так, чтобы интеграция flyway в Grails работала так, как обещано документацией Flyway? Я знаю, что могу сделать это вручную через resources.groovy (рабочий код из моего проекта, сильно вдохновленный код подключаемого модуля Grails Flyway):
if (application.config.flyway.enabled != false) {
flyway(Flyway) { bean ->
bean.initMethod = 'migrate'
dataSource = ref('dataSource')
baselineOnMigrate = application.config.flyway.baselineOnMigrate
}
BeanDefinition sessionFactoryBeanDef = getBeanDefinition('sessionFactory')
if (sessionFactoryBeanDef) {
def dependsOnList = ['flyway'] as Set
if (sessionFactoryBeanDef.dependsOn?.length > 0) {
dependsOnList.addAll(sessionFactoryBeanDef.dependsOn)
}
sessionFactoryBeanDef.dependsOn = dependsOnList as String[]
}
}
но, если возможно, я бы предпочел подход с автоматической настройкой, потому что он поддерживает многие свойства пролетного пути «из коробки», и я могу поддерживать порядок в своих ресурсах.