oracle Hibernate:ManyToOne /多个连接列,其中一列为nullable=true

bejyjqdl  于 2023-10-16  发布在  Oracle
关注(0)|答案(1)|浏览(135)

希望你能帮我。
表A与表B有一个多列联接,其中一个JoinColumns可以为空...

@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(可空)

Map为字符串。组合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)
           )

感谢您的意见和建议!

jljoyd4f

jljoyd4f1#

看起来这场比赛应该有两个部分。
1.**@ManyToOne(...,optional = false)**表示该关系是强制性的,或者它是一个INNER JOIN。INNER JOIN需要在关系上进行直接比较。所以查询的输出形式是正确的。

  1. NULL是值的一种特殊状态,应转换为UNKNOWN值。任何与NULL的直接比较都将得到NULL作为结果。即使将NULL与NULL进行比较,结果也会给予错误。这就是为什么我们在DB服务器中使用特殊的一元操作IS NULL/IS NOT NULL来检查NULL。请记住,一般的逻辑是:NULL不等于另一个NULL,这是您的本地逻辑,基于数据知识和唯一键的存在,在这种特定情况下,某些NULL可以被视为相等的值。因此,本地逻辑需要本地手写查询、方法等。
  • 备注。* 主题中的问题类似于通过多列获得FK- Oracle对此类情况有简单的方法:只有当FK中的所有值都不为NULL时,才验证FK,如果其中一个值为NULL,则不进行验证。你在SQL示例中写的是FK中的FULL方法,并检查附加条件(VALUE 1 = VALUE 2或(VALUE 1 IS NULL和VALUE 2 IS NULL))。Oculle不支持它。只有少数数据库服务器支持这种功能。

相关问题