Hibernate:ManyToOne / 多个联接列,其中一列可为 null=true

问题描述 投票:0回答:1

我希望你能帮助我。

表 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 对象中的列

  • TABLE_B#KEY1_TABLE_B(不为空)
  • TABLE_B#KEY2_TABLE_B(不为空)
  • TABLE_B#GROUP_TABLE_B(可为空)

映射为字符串。 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)
           )

感谢您的想法和想法!

java oracle hibernate-mapping joincolumn
1个回答
0
投票

看来重播应该有两部分。

  1. @ManyToOne(..., 可选 = false) 表示关系是强制性的或者是 INNER JOIN。 INNER JOIN 需要直接比较关系。所以查询的输出形式是正确的。

  2. 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))。奥科不支持。只有少数数据库服务器支持这一点。

© www.soinside.com 2019 - 2024. All rights reserved.