查询实体的子类型字段时,Hibernate生成IN运算符;使用条件API时,会导致生成正确查询的问题

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

想象一下,我有一个域模型,包括4个类Fruit(抽象),Apple,Pear和Kiwi(Fruit的子类),带有一个鉴别器列'type'。让我们假设Apple类有一个鉴别器列值'apple',让我们假设Pear的值为'pear'和Kiwi'kiwi'。最后,每个实体都映射了“每个类的表”策略,因此我们有四个表代表Fruit,apple,kiwi和pear。

关于我的用例:我有一个搜索查询,我想在我的水果上做。我们将寻找成熟的水果,但我们也假设一个苹果有一个甜蜜的领域,一个梨有一个厚度领域,我们想要找到超过10个甜的苹果和超过30个厚的梨。我们的新西兰人没有任何具体要求。

如果我将标准API与元模型一起使用,我将不得不将我的水果Root对象分别转向Apple和梨来查询我们需要测试的字段。

代码示例:

 default List<Fruit> find() {
    return findAll((root, query, cb) -> {
        //Note that we DON'T make a kiwiRoot object here (there's no  need...)
        Root<Apple> appleRoot = cb.treat(root, Apple.class);
        Root<Pear> pearRoot = cb.treat(root, Pear.class);
        //... build up a predicate on the root, apple & pear objects...
}

现在,实际的问题是Hibernate使用in运算符生成一个查询,该运算符只选择我用来构建查询的水果类型!所以我们会得到成熟的水果,但只有10个甜味苹果和30个厚梨的水果!我们在途中失去了新西兰人,因为Hibernate会生成一个IN运算符。

示例伪代码SQL:

SELECT ... FROM fruit 
LEFT OUTER JOIN ... (Apples)
LEFT OUTER JOIN ... (Pears)
LEFT OUTER JOIN ... (Kiwi) -- The Kiwis DO get joined in the query though...
WHERE
  fruit.type IN ('apple', 'pear') --Where did our Kiwi go?
  ... -- ripeness, sweetness, thickness check...

我已经尝试在其中创建一个OR谓词,其中fruit.type IN('kiwi'),但随后查询搞砸了,括号不会去他们应该去的地方......

PS:这显然是一个过于简单的例子,发生此问题的实际代码确实需要使用条件API,因为查询变得非常复杂。

sql hibernate jpa inheritance criteria
1个回答
0
投票

Discriminator列不应与“每类表”策略一起使用。

注释类型DiscriminatorColumn

指定SINGLE_TABLE和JOINED继承映射策略的discriminator列。

https://docs.oracle.com/javaee/7/api/javax/persistence/DiscriminatorColumn.html

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