想象一下,我有一个域模型,该域模型由4类Fruit(抽象),Apple,Pear和Kiwi(Fruit的子类)组成,并带有区分符列“ type”。假设Apple的类的标识符列值为“ apple”,而Pear的值为“ pear”,猕猴桃的值为“ kiwi”。最后,每个实体都采用“每类表”策略进行映射,因此我们有四个表,分别表示水果,苹果,猕猴桃和梨。
关于我的用例:我有一个要对Fruits进行的搜索查询。我们将搜索成熟的水果,但我们还假设一个苹果有一个甜度场,一个梨有一个厚度场,我们想找到甜度大于10的苹果和梨厚度大于30的苹果。 。我们对新西兰人没有任何特殊要求。
如果我将条件API与元模型一起使用,则必须将我的水果Root对象分别向下转换为Apple和pear,以查询我们需要测试的字段。
代码示例:
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,因为查询变得相当复杂。
答案 0 :(得分:0)
“区分类别”列不应与“按类分类”策略一起使用。
注释类型DiscriminatorColumn
指定SINGLE_TABLE和JOINED的鉴别符列 继承映射策略。
https://docs.oracle.com/javaee/7/api/javax/persistence/DiscriminatorColumn.html