org.h2.jdbc.JdbcSQLException:找不到列"ID"

iye*_*and 5 mysql database h2

我的代码中有以下DDL:

CREATE TABLE IF NOT EXISTS SOMETABLE (
  id BIGINT AUTO_INCREMENT NOT NULL,
  ...
  FOREIGN KEY (id) REFERENCES OTHERTABLE(id)
  ...
);
Run Code Online (Sandbox Code Playgroud)

这是OTHERTABLE的定义:

create table "OTHERTABLE" (
  "id" BIGINT GENERATED BY DEFAULT AS IDENTITY(START WITH 1) NOT NULL PRIMARY KEY,
  "code" VARCHAR NOT NULL,
  "name" VARCHAR NOT NULL,
  "enabled" BOOLEAN NOT NULL,
  "app_id" VARCHAR NOT NULL);
Run Code Online (Sandbox Code Playgroud)

请注意,OTIERTABLE由SLICK(Scala ORM Stack)自动生成!

这适用于MySQL(这是我们的dev/prod数据库),但是,我们的单元测试使用H2数据库,并且执行此操作会给出以下堆栈跟踪:

org.h2.jdbc.JdbcSQLException: Column "ID" not found
at org.h2.message.DbException.getJdbcSQLException(DbException.java:329)
at org.h2.message.DbException.get(DbException.java:169)
at org.h2.message.DbException.get(DbException.java:146)
at org.h2.table.Table.getColumn(Table.java:613)
at org.h2.table.IndexColumn.mapColumns(IndexColumn.java:75)
at org.h2.command.ddl.AlterTableAddConstraint.tryUpdate(AlterTableAddConstraint.java:203)
at org.h2.command.ddl.AlterTableAddConstraint.update(AlterTableAddConstraint.java:70)
at org.h2.command.ddl.CreateTable.update(CreateTable.java:169)
at org.h2.command.CommandContainer.update(CommandContainer.java:79)
at org.h2.command.Command.executeUpdate(Command.java:235)
Run Code Online (Sandbox Code Playgroud)

有一种方法可以解决这个问题,那就是在所有地方将id改为"id",但这会改变MySQL中的错误!

由于MySQL是我们的prod数据库,我别无选择,只能忽略单元测试!

在H2数据库方面有解决方案吗?

谢谢

Tho*_*ler 9

如果idOTHERTABLE使用双引号("id")创建时引用该列,则在创建引用完整性约束和查询数据时也必须引用它.基本上,你每次都要引用它.我建议在创建表时不要引用它,因为这样你以后就不必引用了它.引用表示标识符区分大小写.对于MySQL,它可以工作,因为内部MySQL将非引用标识符转换为小写,与其他数据库不同.但对于H2和其他数据库,它不起作用.

以下两个语句适用于MySQL和H2:

CREATE TABLE IF NOT EXISTS OTHERTABLE (
  id BIGINT AUTO_INCREMENT NOT NULL
);
CREATE TABLE IF NOT EXISTS SOMETABLE (
  id BIGINT AUTO_INCREMENT NOT NULL,
  FOREIGN KEY (id) REFERENCES OTHERTABLE(id)
);
Run Code Online (Sandbox Code Playgroud)

因此,如果在第二个语句中出现异常,则很可能使用了另一种方法来创建第一个表(OTHERTABLE).这就是问题所在.

下次,如果您提出问题,还请包含create table第一个表的声明,并发布完整的错误消息.