【问题标题】:org.h2.jdbc.JdbcSQLException: Column "ID" not foundorg.h2.jdbc.JdbcSQLException:找不到列“ID”
【发布时间】:2013-05-24 03:34:05
【问题描述】:

我的代码中有以下 DDL:

CREATE TABLE IF NOT EXISTS SOMETABLE (
  id BIGINT AUTO_INCREMENT NOT NULL,
  ...
  FOREIGN KEY (id) REFERENCES OTHERTABLE(id)
  ...
);

这是 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);

请注意 OTHERTABLE 是由 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)

有一种方法可以解决这个问题,那就是在所有地方都将 id 更改为“id”,但是这种更改在 MySQL 中会中断!!

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

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

谢谢

【问题讨论】:

  • 我还不清楚要求吗?
  • 为什么我在对 H2 数据库执行时收到此错误“未找到列 ID”?以及如何减轻它?希望这足够清楚吗?谢谢!
  • 能否请您发布完整错误消息?
  • 您能否发布您用于OTHERTABLEcreate table 声明?
  • 添加了 OTHERTABLE 的完整堆栈跟踪和定义

标签: mysql database h2


【解决方案1】:

如果在使用双引号 ("id") 创建 OTHERTABLE 时引用列 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)
);

因此,如果您在第二个语句中遇到异常,您很可能使用了不同的方式来创建第一个表 (OTHERTABLE)。这就是问题所在。

下次如果有问题,也请附上第一张表的create table声明,并贴出complete错误信息。

【讨论】:

  • 谢谢!我已经用 OTHERTABLE 的定义和更详细的堆栈跟踪更新了问题。
【解决方案2】:

您正在查看错误的查询

我知道这是在公共论坛上自欺欺人,但我可能不是唯一短视的人。

就我而言,我使用的是 H2 --i.e.不是 MySQL——所以正确处理小写和大写有点令人怀疑。生态系统的其余部分由 Java、spring、JPA 和 Eclipse 组成。

在整个项目中,相同的LONG_COLUMN_NAME 用于大写和小写,所以我从那里开始更改所有 出现(Java 代码、选择查询、创建语句...),但是它并没有消除异常。

然后我将异常追溯到 extractData(ResultSet rs) 方法中提取 LONG_COLUMN_NAME 值的确切行,到执行查询的 DAO 方法,到实际使用的查询字符串... DOH! (this.facePalm(new SoundEffect(SOUNDS.FOR_ALL_THE_OFFICE_TO_HEAR))) 表有列,但这个 test 查询没有:它是从生产查询中复制粘贴的,然后是表和生产代码演变为使用新版本的查询,包括新列,并且测试被抛在后面。所以:确实,LONG_COLUMN_NAME 在结果集中不会以任何形式或方式出现。

将查询字符串字段更改为指向与生产代码中使用的相同的字符串属性解决了该问题。

【讨论】:

    【解决方案3】:

    尝试在项目中使用 FULL PATH 到您的数据库。排除相对路径后,此问题得到解决。在最后的 H2 数据库版本中使用“~/RELATIVE_PATH”有一些错误!不好的例子:“jdbc:h2:~\com\project\db\h2\h2testdb” 好的例子:“jdbc:h2:C:\Users\UserName\IdeaProjects\projectname\com.project\src\main\java\com \test\db\h2\h2testdb"

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-06-22
      • 2017-08-17
      • 2020-04-23
      • 1970-01-01
      • 2019-01-27
      • 2017-12-10
      • 1970-01-01
      • 2013-07-26
      相关资源
      最近更新 更多