Java 如何使jOOQ生成不引用主键的复合外键?

Java 如何使jOOQ生成不引用主键的复合外键?,java,h2,jooq,Java,H2,Jooq,在H2 1.4.194中使用最新的jOOQ时,keys.java中没有为以下(简化)模式生成外键: 按如下方式添加唯一约束没有帮助: CREATE TABLE t (a INT, b INT, PRIMARY KEY (a), UNIQUE (a,b)); CREATE TABLE u (a INT, b INT, FOREIGN KEY (a,b) REFERENCES t (a,b)); 将FK更改为引用主键(无论是简单键还是复合键)将显示FK 通过H2查询FK按预期工作 看起来不像是回归

在H2 1.4.194中使用最新的jOOQ时,
keys.java中没有为以下(简化)模式生成外键:

按如下方式添加唯一约束没有帮助:

CREATE TABLE t (a INT, b INT, PRIMARY KEY (a), UNIQUE (a,b));
CREATE TABLE u (a INT, b INT, FOREIGN KEY (a,b) REFERENCES t (a,b));
将FK更改为引用主键(无论是简单键还是复合键)将显示FK

通过H2查询FK按预期工作

看起来不像是回归(尝试了各种3.xjooq),所以怀疑我是否做错了什么。生成器配置(通过maven插件)如下所示:

<name>org.jooq.util.JavaGenerator</name>
<database>
    <name>org.jooq.util.h2.H2Database</name>
    <includes>.*</includes>
    <excludes />
    <inputSchema>PUBLIC</inputSchema>
</database>
org.jooq.util.JavaGenerator
org.jooq.util.h2.h2数据库
.*
公开的
处理缺少的外键 从jOOQ 3.14开始,如果由于jOOQ中的限制,或者因为架构中实际上没有任何外键,或者因为您正在生成视图,您从生成的输出中缺少外键,那么您可以创建、包括这些外键,并使用如下配置引用它们:


U
A.
B
T
A.
B
有不同的配置方法,例如通过名称引用或列引用等

历史答案(这是一个bug) jOOQ的代码生成器在内部运行的查询如下:

select 
  "CROSS_REFERENCES"."FK_NAME", 
  "CROSS_REFERENCES"."FKTABLE_NAME", 
  "CROSS_REFERENCES"."FKTABLE_SCHEMA", 
  "CROSS_REFERENCES"."FKCOLUMN_NAME", 
  "CONSTRAINTS"."CONSTRAINT_NAME", 
  "CONSTRAINTS"."CONSTRAINT_SCHEMA"
from "INFORMATION_SCHEMA"."CROSS_REFERENCES"
  join "INFORMATION_SCHEMA"."CONSTRAINTS"
  on (
    "CROSS_REFERENCES"."PK_NAME" = "CONSTRAINTS"."UNIQUE_INDEX_NAME"
    and "CROSS_REFERENCES"."PKTABLE_NAME" = "CONSTRAINTS"."TABLE_NAME"
    and "CROSS_REFERENCES"."PKTABLE_SCHEMA" = "CONSTRAINTS"."TABLE_SCHEMA"
  )
where (
  "CROSS_REFERENCES"."FKTABLE_SCHEMA" in (
    'PUBLIC'
  )
  and "CONSTRAINTS"."CONSTRAINT_TYPE" in (
    'PRIMARY KEY', 'UNIQUE'
  )
)
order by 
  "CROSS_REFERENCES"."FKTABLE_SCHEMA" asc, 
  "CROSS_REFERENCES"."FK_NAME" asc, 
  "CROSS_REFERENCES"."ORDINAL_POSITION" asc
查询似乎是正确的,但在H2如何在这些字典视图中编码唯一约束方面似乎存在误解。或者H2中的一个bug

我创造了两个问题,让我们看看哪一个是正确的:

  • H2中的错误:
  • jOOQ中的Bug:

您对
t(a,b)
有唯一的约束或索引吗?它应该与约束一起工作,但可能不与indexI一起工作。在我的非简化示例中,indexI实际上有一个唯一的约束——没有帮助。有趣的是,约束本身被生成为
createUniqueKey(T.T,“X”,T.T.A)--应该是
createUniqueKey(T.T,“X”,T.T.A,T.T.B),对吗?同样,这在信息模式中是正确的。感谢提供详细信息。也许,为了完整起见,您可以用确切的唯一约束更新您的问题吗?我认为这是一个错误。我很快会调查并给你一个答案。嗯,有趣的更新。请问:您的主键没有包含
b
的原因是什么?很好,是的,我可以做到。我的一些表只关心用户,而不关心组织-在这些情况下,我的FKs引用的只是
(id)
,而不是
(id,type)
。我误以为不允许引用非PK的级联删除。然而,这显然是错误的,所以我得救了!
select 
  "CROSS_REFERENCES"."FK_NAME", 
  "CROSS_REFERENCES"."FKTABLE_NAME", 
  "CROSS_REFERENCES"."FKTABLE_SCHEMA", 
  "CROSS_REFERENCES"."FKCOLUMN_NAME", 
  "CONSTRAINTS"."CONSTRAINT_NAME", 
  "CONSTRAINTS"."CONSTRAINT_SCHEMA"
from "INFORMATION_SCHEMA"."CROSS_REFERENCES"
  join "INFORMATION_SCHEMA"."CONSTRAINTS"
  on (
    "CROSS_REFERENCES"."PK_NAME" = "CONSTRAINTS"."UNIQUE_INDEX_NAME"
    and "CROSS_REFERENCES"."PKTABLE_NAME" = "CONSTRAINTS"."TABLE_NAME"
    and "CROSS_REFERENCES"."PKTABLE_SCHEMA" = "CONSTRAINTS"."TABLE_SCHEMA"
  )
where (
  "CROSS_REFERENCES"."FKTABLE_SCHEMA" in (
    'PUBLIC'
  )
  and "CONSTRAINTS"."CONSTRAINT_TYPE" in (
    'PRIMARY KEY', 'UNIQUE'
  )
)
order by 
  "CROSS_REFERENCES"."FKTABLE_SCHEMA" asc, 
  "CROSS_REFERENCES"."FK_NAME" asc, 
  "CROSS_REFERENCES"."ORDINAL_POSITION" asc