当前位置: 首页 > 知识库问答 >
问题:

在hsqldb上生成jpa auto-dll表后运行liquibase变更日志

柴砚文
2023-03-14

案子就是这样。我有只包含插入内容的liquibase changelog。我试图强制Spring Boot使用基于@Entities的JPA初始化数据库(hsqldb)模式,然后执行liquibase changelog。不幸的是,Spring Boot是按顺序进行的。

我检查了LiquibaseAutoConfiguration,它有:

@AutoConfigureAfter({ DataSourceAutoConfiguration.class,
        HibernateJpaAutoConfiguration.class })

所以它是在HibernateJPA自动配置之后执行的,但是Spring Boot仍然没有按照我希望的方式执行;)。

Spring Boot版本:1.3.0。发布Liquibase核心版本:3.5.1

提前感谢您提供的任何naswer

共有3个答案

笪昌翰
2023-03-14

我刚刚把Spring Boot升级到了2.5.3,也遇到了同样的问题。我通过使用classCustomSpringLiquibase(Kotlin版本)解决了这个问题:

class CustomSpringLiquibase(
        private var springLiquibase: SpringLiquibase
) : InitializingBean, BeanNameAware, ResourceLoaderAware {

    companion object {
        private val LOGGER = LoggerFactory.getLogger(CustomSpringLiquibase::class.java)
    }

    @Throws(LiquibaseException::class)
    override fun afterPropertiesSet() {
        LOGGER.info("Init Liquibase")
        springLiquibase.afterPropertiesSet()
    }

    override fun setBeanName(name: String) {
        springLiquibase.beanName = name
    }

    override fun setResourceLoader(resourceLoader: ResourceLoader) {
        springLiquibase.resourceLoader = resourceLoader
    }
}

在我的SpringBootApplication课程中,我添加了以下内容(Java版本):

@Bean
@DependsOn(value = "entityManagerFactory")
public CustomSpringLiquibase liquibase() {
    LiquibaseProperties liquibaseProperties = liquibaseProperties();
    SpringLiquibase liquibase = new SpringLiquibase();
    ....
    return new CustomSpringLiquibase(liquibase);
}
陶高峻
2023-03-14

Radek Postołowicz提供的解决方案为我提供了相当长的一段时间,但在升级到spring boot 2.5.0后不再有效。我认为可以通过向应用程序添加以下属性来完全替换它。属性(或yml):

spring.jpa.defer-datasource-initialization=true

发行说明中也提到了这一点。

陶沛
2023-03-14

可能的解决方案是禁用自动引导liquibase运行通过application.properties

spring.jpa.hibernate.ddl-auto=create
liquibase.enabled=false

然后手动配置SpringLiquibasebean以依赖于entityManagerFactory

import javax.sql.DataSource;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceBuilder;
import org.springframework.boot.autoconfigure.liquibase.LiquibaseProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.DependsOn;

import liquibase.integration.spring.SpringLiquibase;

@SpringBootApplication
public class DemoApplication {

    @Autowired
    private DataSource dataSource;

    @Bean
    public LiquibaseProperties liquibaseProperties() {
        return new LiquibaseProperties();
    }

    @Bean
    @DependsOn(value = "entityManagerFactory")
    public SpringLiquibase liquibase() {
        LiquibaseProperties liquibaseProperties = liquibaseProperties();
        SpringLiquibase liquibase = new SpringLiquibase();
        liquibase.setChangeLog(liquibaseProperties.getChangeLog());
        liquibase.setContexts(liquibaseProperties.getContexts());
        liquibase.setDataSource(getDataSource(liquibaseProperties));
        liquibase.setDefaultSchema(liquibaseProperties.getDefaultSchema());
        liquibase.setDropFirst(liquibaseProperties.isDropFirst());
        liquibase.setShouldRun(true);
        liquibase.setLabels(liquibaseProperties.getLabels());
        liquibase.setChangeLogParameters(liquibaseProperties.getParameters());
        return liquibase;
    }

    private DataSource getDataSource(LiquibaseProperties liquibaseProperties) {
        if (liquibaseProperties.getUrl() == null) {
            return this.dataSource;
        }
        return DataSourceBuilder.create().url(liquibaseProperties.getUrl())
            .username(liquibaseProperties.getUser())
            .password(liquibaseProperties.getPassword()).build();
    }

    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }
}

然而,我强烈建议使用liquibase来构建模式。我相信它的设计(参见org.springframework.boot.autoconfigure.liquibase.LiquibaseAutoConfiguration.LiquibaseJpaDependencyConfiguration)是为了在hibernate的ddl auto之前运行,这样就可以设置ddl auto=validate,并让liquibase模式通过hibernate验证。

 类似资料:
  • 该项目 为了寻找解决方案,我首先使用maven在执行LiquiBase:Update时将变更日志的SVN修订版存储到中。基于修订版号检索变更日志容易出错。 我已经花了一周的时间来寻找一个健壮的解决方案,在谷歌上搜索了几个小时,构建了几个测试用例(使用了适应的父级和具体的POM,部分使用了maven scm插件等等),但没有运气。最初,我计划使用LiquiBase:tag存储文件路径+修订,但只有当

  • 我还可以为不同的DBs生成不同的变更集,只要它在相同的migration.xml中即可 有什么办法可以做到这一点吗?

  • 我无法从Spring Boot项目的JPA实体生成初始更改日志。我的pom.xml如下: 下面是液化酶。属性文件: 当我运行命令时 它在DB[Full log on Pastebin]的

  • 我是liquibase的新手,我想在生产中的数据库上使用它。这是一个很小的应用程序,但我不想手工创建模式,而是想使用更专业的东西,比如LiquiBase。 我计划做的是在生产中的当前模式和新模式之间为新应用程序准备一个changelog。我已经遵循了许多教程,但仍然缺少一些东西。输出changelog.xml总是导入所有模式,并且与现有模式没有区别。我看到liquibase必须创建表DATABAS

  • 我有一个现有的数据库,并使用了generateChangeLog命令行来创建初始的ChangeLog。这很好:-) 但现在我希望开发人员使用他们已经知道/使用的所有工具/流程来开发数据库和代码,并使用脚本生成任何适当的增量更改集。 即:使用当前更改日志(属性文件中的 changeLogFile)作为基本引用,对开发人员数据库的当前状态(属性文件中的 url/用户名/密码)执行差异。 似乎没有简单的

  • 我试图在命令提示符下执行命令: