首页 > 解决方案 > 在 H2 内存数据库的 liquibase 迁移中找不到列

问题描述

我不得不用 H2 内存数据库替换我的 PostgreSQL 数据库,我的迁移开始失败。创建表脚本运行但插入失败。

ChangeSet classpath:database/changelog/create-default-user.xml::createUserTable::ethero ran successfully in 7ms
Change Set classpath:database/changelog/create-default-user.xml::insertDefaultUser::ethero failed.  Error: Column "username" not found; SQL statement:

错误堆栈跟踪

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'liquibase' defined in class path resource [org/springframework/boot/autoconfigure/liquibase/LiquibaseAutoConfiguration$LiquibaseConfiguration.class]: Invocation of init method failed; nested exception is liquibase.exception.MigrationFailedException: Migration failed for change set classpath:database/changelog/create-default-user.xml::insertDefaultUser::ethero:
     Reason: liquibase.exception.DatabaseException: Column "username" not found; SQL statement:
INSERT INTO usr ("username", "password") VALUES ('admin', 'password') [42122-200] [Failed SQL: (42122) INSERT INTO usr ("username", "password") VALUES ('admin', 'password')]

创建表脚本

create table user_authorities (username varchar(255) not null , authorities varchar(255));
create table usr (username varchar(255) not null , password varchar(255), image_url varchar(255))

插入用户脚本

INSERT INTO usr ("username", "password") VALUES ('admin', 'password');
INSERT INTO user_authorities ("username", "authorities") VALUES ('admin', 'ADMIN');
INSERT INTO user_authorities ("username", "authorities") VALUES ('admin', 'USER');

春季启动配置

spring:
  profiles:
    active: dev
  datasource:
    url: jdbc:h2:mem:pc;DB_CLOSE_DELAY=-1;
    username: sa
    password: sa
    driver-class-name: org.h2.Driver
  jpa:
    generate-ddl: true
    hibernate:
      ddl-auto: update
    show-sql: true

  liquibase:
    change-log: classpath:database/changelog-master.xml
    url: jdbc:h2:mem:pc;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE

春季启动版本:2.4.3

标签: javaspring-booth2liquibase

解决方案


PostgreSQL 和其他一些 DBMS 与其他 DBMS 不同:它们将不带引号的标识符转换为小写。H2 和许多其他人将不带引号的标识符转换为大写,这种行为实际上是一种标准行为。

如果出于某种原因你想同时使用这两个 DBMS,你可以添加;DATABASE_TO_LOWER=TRUE到 H2 的 JDBC url,这个参数 H2 将像 PostgreSQL 一样处理标识符的大小写。

但是,如果您只想使用 H2,最好不要使用此类设置并调整您的 SQL 以在带引号的标识符中使用大写字母。

无论如何,混合带引号和不带引号的标识符是一种不好的做法。通常最好总是引用或从不引用它们。请注意,有各种保留字,这些字不能用作不带引号的标识符。


推荐阅读