5

我的代码中有以下 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 数据库端有解决方案吗?

谢谢

4

3 回答 3

9

如果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第一张表的说明,并贴出完整的错误信息。

于 2013-05-29T10:45:18.813 回答
0

您正在查看错误的查询

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

就我而言,我使用的是 H2——即不是 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))) 表有列,但这个测试查询没有:它是从生产查询中复制粘贴的,然后表和生产代码演变为使用新版本的查询,包括新列,并且测试被留下. 所以:确实LONG_COLUMN_NAME在结果集中找不到任何形式或方式。

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

于 2018-08-24T07:41:38.070 回答
0

尝试在项目中使用 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"

于 2019-02-27T22:47:56.577 回答