我希望你能帮助我。
表 A 与表 B 具有多列联接,其中联接列之一可以为空...
@Entity
@Table(name = "TABLE_A")
public class TableA {
@ManyToOne(fetch = FetchType.EAGER, optional = false)
@JoinColumns({
@JoinColumn(name = "KEY1_TABLE_A", referencedColumnName = "KEY1_TABLE_B"),
@JoinColumn(name = "KEY2_TABLE_A", referencedColumnName = "KEY2_TABLE_B"),
@JoinColumn(name = "GROUP_TABLE_A", referencedColumnName = "GROUP_TABLE_B", nullable = true)})
private TableB typeB;
}
在 TableB 对象中的列
映射为字符串。 KEY1_TABLE_B /KEY2_TABLE_B /GROUP_TABLE_B 是唯一的键。
生成的SQL如下(缩短)
SELECT
*
FROM
table_a this_
INNER JOIN table_b b_ ON
this_.KEY1_TABLE_A = b_.KEY1_TABLE_B AND
this_.KEY2_TABLE_A = b_.KEY2_TABLE_B AND
this_.GROUP_TABLE_A = b_.GROUP_TABLE_B <-- here is the issue: works only with "is not null" on Oracle
WHERE
this.XYZ=<some-conditions-here>;
如果我直接编写SQL,它应该是这样的
on ... AND (
(this_.GROUP_TABLE_A = b_.GROUP_TABLE_B)
OR (this_.GROUP_TABLE_A is null and b_.GROUP_TABLE_B is null)
)
感谢您的想法和想法!
看来重播应该有两部分。
@ManyToOne(..., 可选 = false) 表示关系是强制性的或者是 INNER JOIN。 INNER JOIN 需要直接比较关系。所以查询的输出形式是正确的。
NULL 是值的一种特殊状态,应翻译为 UNKNOWN 值。与 NULL 的任何直接比较都会得出 FALSE 结果。即使将 NULL 与 NULL 进行比较也会得到 FALSE 结果。这就是为什么我们在数据库服务器中有特殊的一元操作 IS NULL/IS NOT NULL 来检查 NULL。请记住,一般逻辑是:NULL 不等于另一个 NULL,它是您的本地逻辑,基于数据知识和唯一键的存在,在这种特殊情况下,某些 NULL 可以被视为相等的值。因此,本地逻辑需要本地手写查询、方法等。
备注。主题中的问题类似于由多个列组成的 FK - Oracle 对于这种情况有简单的方法:仅当 FK 中的所有值都不为 NULL 时才验证 FK,如果其中之一为 NULL,则不验证 FK验证发生。您在 SQL 示例中编写的内容意味着 FK 中的 FULL 方法并检查附加条件(VALUE1 = VALUE2 或(VALUE1 IS NULL 和 VALUE2 IS NULL))。奥科不支持。只有少数数据库服务器支持这一点。