Hibernate在评估子属性时,where或statement不起作用

时间:2016-06-21 14:28:31

标签: hibernate grails

标题说明问题本身。我有这个Grails Domain类。

class IonicBond {
    ...

    static hasMany = [
        typeIIs: TypeII,
        typeRs: TypeR,
    ]

    static constraints = {
        typeIIs nullable: true
        typeRs nullable: true
    }
}

我需要根据IonicBond属性查询hasMany的实例。像这样:

ArrayList<IonicBond> list = IonicBond.createCriteria().list {
    or {
        typeIIs {
            eq("classCode", "WD996")
        }
        typeRs {
            eq("classCode", "WD996")
        }
    }
}

我需要为此声明做一些查询:&#34;让IonicBond个孩子或TypeII个孩子中的任何一个TypeR全部classCode IonicBond等于&#39; WD996&#39;&#34; 。问题是此查询仅在TypeII实例同时包含TypeR IonicBond子项时才有效。它不包括:

  1. TypeRclass个孩子TypeII值为&#34; WD996&#34;但没有IonicBond孩子。
  2. TypeIIclass个孩子TypeR值为&#34; WD996&#34;但没有"permissions": [ "tabs", "storage", "contextMenus", "background", "https://twitter.com/", "http://twitter.com/" ], 孩子。
  3. 如何将其包含在结果集中?

3 个答案:

答案 0 :(得分:1)

试试这个解决方案:

ArrayList<IonicBond> list = IonicBond.where { typeRs { classCode == "WD996" } || typeIIs { classCode == "WD996" } }.list()

答案 1 :(得分:0)

Detached Criteria是查询GORM的一种方法。首先使用要为其执行查询的域类的名称创建DetachedCriteria。然后你打电话给方法&#39; build&#39;用&#39;其中&#39;查询或条件查询。

def criteria = new DetachedCriteria(IonicBond).build {

    or {
            typeIIs {
                eq("classCode", "WD996")
            }
            typeRs {
                eq("classCode", "WD996")
            }
        }

}
def result = criteria.list()

答案 2 :(得分:0)

我发现默认情况下createCriteria()使用INNER JOIN,这意味着它实际上不包含只有IonicBond个孩子的typeIIs个实例,或typeRs,只有两个。解决方案是使用LEFT JOIN

将其更改为createAlias()
import org.hibernate.Criteria

...
    ArrayList<IonicBond> list = IonicBond.createCriteria().list {
        createAlias('typeIIs', 'typeIIs', Criteria.LEFT_JOIN)
        createAlias('typeRs', 'typeRs', Criteria.LEFT_JOIN)

        or {
            eq("typeIIs.classCode", "WD996")
            eq("typeRs.classCode", "WD996")
        }
    }
  

请注意,即使您将其所有子项设置为LEFT JOIN,Hibernate也不会将constraints.nullable: true用作默认联接。您必须手动说明。