我有一个Hibernate / JPA数据模型,它允许我将对象(MyObj)放入各种类别(MyCategory)。每个类别可以具有0个或更多个子类别,而不具有分配给它们的分类(MyClassification)的类别。数据模型如下所示:
public class MyObj {
…
protected MyCategory category = null;
…
}
public class MyCategory {
…
protected MyClassification classification=null;
protected List<MyCategory> childCategories=null;
protected MyCategory parentCategory=null;
…
}
public class MyClassification {
…
}
我希望能够根据分类,类别或子类别查询MyObj实例。例如,如果我有3个分类(classA,classB和classC)和6个类别(例如categoryA1,categoryA2,categoryB1等,其中名称对应于分类),并且每个类别都有3个子类别(例如subcatA1, subcatA2,subcatA3,subcatB1等。)我想做这样的查询:
我创建了一些我认为可以完成此任务的NamedQueries。它们适用于已将MyObj实例分配给子类别的实例。但是,如果我将MyObj实例放在一个类别(没有子类别)和基于类的查询中,我看不到它。我只看到子类别中的MyObj实例。我的查询看起来像这样:
MyObj.findByClass = "SELECT DISTINCT o FROM MyObj o WHERE (o.category.classification = :classification OR o.category.parentCategory.classification = :classification)"
MyObj.findByCategory = "SELECT DISTINCT o FROM MyObj o WHERE (o.category = :category OR o.category.parentCategory = :category)"
有人能告诉我这些查询的逻辑错误在哪里吗?有没有更好的方法来完成我追求的目标?
答案 0 :(得分:2)
您的查询存在的问题是,o.category.parentCategory
的编写方式与inner join category cat on cat.id=o.parent_category
类似,如果parentCategory
为NULL
,您将无法获得任何结果。
因此,点导航意味着内部联接会导致OR
语句出现问题。您必须使用明确的LEFT JOINs
或UNION
个查询。
在旁注中,QueryDSL允许编写如下语句:
from(QCategory.category)
.where(QCategory.category.classification.eq(classification).or(QCategory.category.left().parentCategory().left().classification.eq(classification))
.listDisticnt(QCategory.category)
SELECT DISTINCT o from MyObj o WHERE(o.category.classification =:classification OR o.category.parentCategory.classification =:classification)“
答案 1 :(得分:0)
我认为你在OR之后的第一个查询中缺少“分类”:
MyObj.findByClass = "SELECT DISTINCT o FROM MyObj o WHERE (o.category.classification = :classification OR o.category.parentCategory.classification = :classification)"
另一方面,我的感觉是遍历对象图比发出HQL查询更直接