Hibernate: ManyToOne / multiple join columns with one column



我希望你能在这方面帮助我。

表A具有到表B的多列联接,其中一个JoinColumns可以为null。。。

@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(可为null(

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

谢谢你的想法和想法!

似乎回放应该有两部分。

  1. @ManyToOne(…,optional=false(认为该关系是强制性的或是INNER JOIN。INNER JOIN需要在关系中进行直接比较。因此,查询的输出形式是正确的。

  2. NULL是值的一种特殊状态,应转换为UNKNOWN值。任何与NULL的直接比较结果都是FALSE。即使将NULL与NULL进行比较,结果也会是FALSE。这就是为什么我们在DB服务器IS NULL/IS NOT NULL中有特殊的一元运算来检查NULL。请记住,一般逻辑是:NULL不等于另一个NULL,它是您的本地逻辑,基于数据知识和唯一密钥的存在,在这种特殊情况下,一些NULL可以被视为相等的值。因此,本地逻辑需要本地手写查询、方法等。

备注主题中的问题类似于通过多列进行FK-Oracle对这种情况采用SIMPLE方法:只有当FK中的所有值都不为NULL时才验证FK,如果其中一个值为NULL,则不会进行验证。您在SQL示例中所写的内容表示FK中的FULL方法,并检查附加条件(VALUE1=VALUE2或(VALUE1为NULL,VALUE2为NULL((。Oacle不支持它。而且只有少数数据库服务器支持它。

最新更新