尝试通过 liquibase、postgresql、spring boot 创建新数据库。结果->“数据库更改日志”不存在

Posted

技术标签:

【中文标题】尝试通过 liquibase、postgresql、spring boot 创建新数据库。结果->“数据库更改日志”不存在【英文标题】:Trying to create new database via liquibase, postgresql, spring boot. Result-> "databasechangelog" does not exist 【发布时间】:2016-03-07 13:48:04 【问题描述】:

我正在尝试使用 liquibase (3.3)、postgresql (9.4) 和 spring-boot 创建一个新的数据库模式。相关代码和异常贴在下面。

我在本地 postgresql 服务器上创建了空的测试数据库。

Error starting ApplicationContext. To display the auto-configuration report enabled debug logging (start with --debug)


2015-12-02 20:20:08.971 ERROR 3823 --- [           main] o.s.boot.SpringApplication               : Application startup failed

org.springframework.dao.InvalidDataAccessResourceUsageException: could not extract ResultSet; SQL [n/a]; nested exception is org.hibernate.exception.SQLGrammarException: could not extract ResultSet
    at org.springframework.orm.jpa.vendor.HibernateJpaDialect.convertHibernateAccessException(HibernateJpaDialect.java:238)
    at org.springframework.orm.jpa.vendor.HibernateJpaDialect.translateExceptionIfPossible(HibernateJpaDialect.java:221)
    at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.translateExceptionIfPossible(AbstractEntityManagerFactoryBean.java:417)
    at org.springframework.dao.support.ChainedPersistenceExceptionTranslator.translateExceptionIfPossible(ChainedPersistenceExceptionTranslator.java:59)
    at org.springframework.dao.support.DataAccessUtils.translateIfNecessary(DataAccessUtils.java:213)
    at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:147)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
    at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:653)
    at com.test.liquibase.repository.DatabaseChangeLogRepository$$EnhancerBySpringCGLIB$$53249fb1.findDatabaseChangeLogs(<generated>)
    at com.test.liquibase.LiquibaseChangeLogReporter.onApplicationEvent(LiquibaseChangeLogReporter.java:49)
    at com.test.liquibase.LiquibaseChangeLogReporter.onApplicationEvent(LiquibaseChangeLogReporter.java:29)
    at org.springframework.context.event.SimpleApplicationEventMulticaster.invokeListener(SimpleApplicationEventMulticaster.java:151)
    at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:128)
    at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:331)
    at org.springframework.context.support.AbstractApplicationContext.finishRefresh(AbstractApplicationContext.java:773)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:483)
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:686)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:320)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:957)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:946)
    at com.test.schema.dbInitializer.main(LearnSchemaInitializer.java:30)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:497)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:140)
Caused by: org.hibernate.exception.SQLGrammarException: could not extract ResultSet
    at org.hibernate.exception.internal.SQLStateConversionDelegate.convert(SQLStateConversionDelegate.java:123)
    at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:49)
    at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:126)
    at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:112)
    at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.extract(ResultSetReturnImpl.java:91)
    at org.hibernate.loader.Loader.getResultSet(Loader.java:2066)
    at org.hibernate.loader.Loader.executeQueryStatement(Loader.java:1863)
    at org.hibernate.loader.Loader.executeQueryStatement(Loader.java:1839)
    at org.hibernate.loader.Loader.doQuery(Loader.java:910)
    at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:355)
    at org.hibernate.loader.Loader.doList(Loader.java:2554)
    at org.hibernate.loader.Loader.doList(Loader.java:2540)
    at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2370)
    at org.hibernate.loader.Loader.list(Loader.java:2365)
    at org.hibernate.loader.hql.QueryLoader.list(QueryLoader.java:497)
    at org.hibernate.hql.internal.ast.QueryTranslatorImpl.list(QueryTranslatorImpl.java:387)
    at org.hibernate.engine.query.spi.HQLQueryPlan.performList(HQLQueryPlan.java:236)
    at org.hibernate.internal.SessionImpl.list(SessionImpl.java:1264)
    at org.hibernate.internal.QueryImpl.list(QueryImpl.java:103)
    at org.hibernate.jpa.internal.QueryImpl.list(QueryImpl.java:573)
    at org.hibernate.jpa.internal.QueryImpl.getResultList(QueryImpl.java:449)
    at org.hibernate.jpa.criteria.compile.CriteriaQueryTypeQueryAdapter.getResultList(CriteriaQueryTypeQueryAdapter.java:67)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:497)
    at org.springframework.orm.jpa.SharedEntityManagerCreator$DeferredQueryInvocationHandler.invoke(SharedEntityManagerCreator.java:362)
    at com.sun.proxy.$Proxy51.getResultList(Unknown Source)
    at com.test.liquibase.repository.DatabaseChangeLogRepository.findDatabaseChangeLogs(DatabaseChangeLogRepository.java:38)
    at com.test.liquibase.repository.DatabaseChangeLogRepository$$FastClassBySpringCGLIB$$d54e8385.invoke(<generated>)
    at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
    at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:717)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
    at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:136)
    ... 20 common frames omitted
Caused by: org.postgresql.util.PSQLException: ERROR: relation "databasechangelog" does not exist
  Position: 382
    at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2182)
    at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:1911)
    at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:173)
    at org.postgresql.jdbc2.AbstractJdbc2Statement.execute(AbstractJdbc2Statement.java:645)
    at org.postgresql.jdbc2.AbstractJdbc2Statement.executeWithFlags(AbstractJdbc2Statement.java:495)
    at org.postgresql.jdbc2.AbstractJdbc2Statement.executeQuery(AbstractJdbc2Statement.java:380)
    at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.extract(ResultSetReturnImpl.java:82)
    ... 49 common frames omitted

application.properties

liquibase.change-log=classpath:/liquibase/changelog.xml
liquibase.default-schema=test
liquibase.user=postgres
liquibase.password=postgres

spring.datasource.driver-class-name=org.postgresql.Driver
spring.datasource.username=postgres
spring.datasource.password=postgres
spring.datasource.host=localhost
spring.datasource.port=5432
spring.datasource.database=test
spring.datasource.url=jdbc:postgresql://$spring.datasource.host:$spring.datasource.port/$spring.datasource.database?useUnicode=true&characterEncoding=utf8&autoReconnect=true

spring.jpa.database-platform=org.hibernate.dialect.PostgreSQLDialect

spring.jpa.hibernate.naming-strategy=org.hibernate.cfg.EJB3NamingStrategy
spring.jpa.show-sql=true
spring.jpa.generate-ddl=true

更改日志.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <databaseChangeLog
            xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
            xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog
            http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.3.xsd">

        <include file="data/initial_schema.liquibase.xml" relativeToChangelogFile="true"/>

    </databaseChangeLog>

initial_schema.liquibase.xml
<?xml version="1.0" encoding="UTF-8"?>
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
                   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                   xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog
                   http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.1.xsd ">

    <changeSet id="1.0" author="">

        <createTable tableName="TestTable">
            <column name="test1Id" type="bigint" autoIncrement="true">
                <constraints primaryKey="true" nullable="false"/>
            </column>
            <column name="orgId" type="varchar(50)">
                <constraints nullable="false"/>
            </column>
            <column name="title" type="varchar(50)">
                <constraints nullable="false"/>
            </column>
            <column name="cartId" type="bigint">
                <constraints nullable="false"/>
            </column>
        </createTable>
    </changeSet>

dbInitializer.java

@ComponentScan( "com.test", "com.test.liquibase", "com.test.liquibase.repository" )
@Configuration
@EntityScan("com.test.liquibase")
@EnableAutoConfiguration
@EnableTransactionManagement
public class dbInitializer

    private static final Logger LOG = dbInitializer.class);

    public static void main(String[] args) throws Exception
    
        try
        
            SpringApplication.run(dbInitializer.class, args);
        
        catch(Exception ex)
        
            LOG.error("Execution failed.", ex);
            System.exit(1);
        

        System.exit(0);
    

【问题讨论】:

【参考方案1】:

当您运行 liquibase 基本脚本时,它会创建两个额外的表来跟踪 liquibase 的数据库更新。

表名

    数据库更改日志 数据库更改日志锁

但您不需要手动创建这些。它会在运行 liquibase 脚本时自动创建。

我认为您必须手动(命令行)运行 liquibase 脚本来创建这些表和其他表(仅一次),然后根据您的 liquibase 脚本增量更新数据库。

【讨论】:

非常感谢您的建议 @alex17883 在 *** 上说 thx 正在支持答案(如果它解决了您的问题,甚至接受它)。

以上是关于尝试通过 liquibase、postgresql、spring boot 创建新数据库。结果->“数据库更改日志”不存在的主要内容,如果未能解决你的问题,请参考以下文章

将 UUID 值插入 PostgreSQL 数据库时出现 Liquibase 问题

Liquibase 和 Docker

OneToMany 关系不能在春天用 liquibase 保存

找不到数据库驱动程序:org.postgresql.Driver

自动回滚不适用于 Postgresql 上的 liquibase

JOOQ 可以为 H2/Postgresql 别名 Liquibase JSONB 数据类型吗