【问题标题】:HQL: Multiple JOIN Collection Query Returns NothingHQL:多个 JOIN 集合查询不返回任何内容
【发布时间】:2013-10-28 15:26:50
【问题描述】:

我正在尝试编写返回以下内容的 HQL 查询:

他们的属性标签在我的包含标签中
或者我的 propertyTags 在他们的包含标签中,
并且他们的属性标签不在我的排除标签中,
并且我的 propertyTags 不在他们的 excludeTags 中。

这是我目前得到的:

def thePropertyTags = this.propertyTags
if(thePropertyTags == null || thePropertyTags.size() == 0) {
    thePropertyTags = [ Tag.UNUSED_TAG ]
}

def theInclusions = this.inclusionTags
if(theInclusions == null || theInclusions.size() == 0) {
    theInclusions = [ Tag.UNUSED_TAG ]
}

def theExclusions = this.exclusionTags
if(theExclusions == null || theExclusions.size() == 0) {
    theExclusions = [ Tag.UNUSED_TAG ]
}

List<MyDomain> objects = MyDomain.executeQuery("""
    SELECT DISTINCT o
    FROM MyDomain o

    JOIN o.propertyTags as propertyTags
    JOIN o.exclusionTags as exclusions
    JOIN o.inclusionTags as inclusions

    WHERE o.id != :id
    AND o.isActive = true

    AND (
        exclusions IS NULL
        OR exclusions IS EMPTY
        OR exclusions NOT in (:propertyTags)
    )

    AND propertyTags NOT in (:exclusions)

    AND (
        inclusions in (:propertyTags)
        OR propertyTags in (:inclusions)
    )

""", [id: id, inclusions: theInclusions, exclusions: theExclusions, propertyTags: thePropertyTags])

问题是不管包含/属性标签匹配,加入排除标签不会返回任何内容。删除所有排除子句仍然不返回任何内容,获得任何返回的唯一方法是完全删除 JOIN。

域:

MyDomain {
    boolean isActive = true

    static hasMany = [propertyTags: Tag, inclusionTags: Tag, exclusionTags: Tag]

    static constraints = {
        propertyTags(nullable: false)
        inclusionTags(nullable: false)
        exclusionTags(nullable: false)
    }
}

Tag {
    private static final List<Integer> TAG_TYPES = [...]

    String name
    int type
    String description

    static constraints = {
        name(unique: true, nullable: false, blank: false)
        type(inList: [TAG_TYPES])

        description(nullable: true, blank: true)
    }
}

更新:

我已将包含/排除更改为 LEFT JOIN,就像这样,但如果排除在查询中,仍然没有返回记录:

List<MyDomain> objects = MyDomain.executeQuery("""
    SELECT DISTINCT o
    FROM MyDomain o

    JOIN o.propertyTags as propertyTags
    LEFT JOIN o.exclusionTags as exclusions
    LEFT JOIN o.inclusionTags as inclusions

    WHERE o.id != :id
    AND o.isActive = true

    AND exclusions NOT in (:propertyTags)
    AND propertyTags NOT in (:exclusions)

    AND (
        inclusions in (:propertyTags)
        OR propertyTags in (:inclusions)
    )

""", [id: id, inclusions: theInclusions, exclusions: theExclusions, propertyTags: thePropertyTags])

【问题讨论】:

  • 域类长什么样子?
  • @dmahapatro 添加了域名

标签: java grails hql


【解决方案1】:

我看到的第一个问题是您正在对排除标签进行内部连接。这将确保它只返回具有排除标签的记录。您也可以使用没有包含标签的“MyDomain”来满足“他们的 propertyTags 在我的包含标签中”,因此您也应该离开加入它

试试这个

LEFT JOIN o.exclusionTags as exclusions
LEFT JOIN o.inclusionTags as inclusions

那么你应该能够简单地做到这一点:

AND (
    exclusions NOT in (:propertyTags)
)

编辑: 好的,我知道了 - 问题是不在。Hibernate 对此很奇怪。在我发布原始答案之前,我没有意识到所有标签都是可以为空的 false,因此进行左连接是没有意义的。

MyDomain.executeQuery("select distinct m from MyDomain m join m.propertyTags as pt join m.inclusionTags as it where m.id != :id and m.isActive = true and (pt in (:inclusionTags) or it in (:propertyTags)) and m not in (select m from MyDomain m join m.propertyTags as pt where pt in (:exclusionTags)) and m not in (select m from MyDomain m join m.exclusionTags as et where et in (:propertyTags))", [id: id, inclusionTags: theInclusions, propertyTags: thePropertyTags, exclusionTags: theExclusions])

【讨论】:

  • 我用 LEFT JOIN 示例更新了问题,但如果查询中加入了排除项,它仍然不返回任何内容
  • 感谢您的帮助,实际上我今天早些时候最终找到了相同的解决方案。无论如何,赏金是你的,谢谢!
猜你喜欢
  • 2012-04-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-04-24
  • 2013-09-10
  • 1970-01-01
相关资源
最近更新 更多