我的代码中有以下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);
请注意,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)
有一种方法可以解决这个问题,那就是在所有地方将id更改为“id”,但这会改变MySQL中的错误!!
由于MySQL是我们的prod数据库,我别无选择,只能忽略单元测试!!
在H2数据库方面有解决方案吗?
由于
答案 0 :(得分:7)
如果在使用双引号(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
语句,并发布完整错误消息。
答案 1 :(得分:0)
我知道这在一个公共论坛上自欺欺人,但我可能并不是唯一的目光短浅的人。
就我而言,我正在使用H2-即不是MySQL,因此对小写和大写的正确处理有些怀疑。生态系统的其余部分由Java,spring,JPA和Eclipse组成。
在整个项目中,大写和小写都使用相同的LONG_COLUMN_NAME
,所以我从那里开始,更改了所有出现的内容(Java代码,选择查询,创建语句...) ,但并没有消除异常。
然后,我追溯异常,追溯到extractData(ResultSet rs)
方法中的确切行,提取LONG_COLUMN_NAME
的值,追溯到执行查询的DAO方法,再追溯到实际使用的查询字符串... < strong> DOH! (this.facePalm(new SoundEffect(SOUNDS.FOR_ALL_THE_OFFICE_TO_HEAR))
)表中具有该列,但是此 test 查询没有:它是从生产查询中复制粘贴的,然后表格和生产代码演变为使用新版本的查询,包括新列,并且留下了测试。因此:实际上,在结果集中找不到LONG_COLUMN_NAME
的形式。
更改查询字符串字段以指向与生产代码中使用的字符串属性相同的问题。
答案 2 :(得分: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“