我有一个域类
class Url {
UUID id
String url
static hasMany = [
indications:UrlIndication
]
...
}
并且
class UrlIndication {
UUID id
String name
static belongsTo = Url
...
}
我想选择网址,以便它在给定列表UrlIndication
中包含所有必需的indicationsId
元素。
为此我使用像这样的关联and
标准:
indications {
and {
indicationsId.each{
indication->
eq ('id',UUID.fromString(indication as String))
}
}
}
然而,我得到的只是一个空洞的结果。你能建议任何修改/其他方法,以便我可以这样做吗?提前致谢
答案 0 :(得分:1)
您的查询返回一个空列表,因为它等同于表达式(伪代码):if 1 = 1 and 1 = 2 and 1 = 3
这样的表达总是错误的。由于@innovatism所描述的原因,in
或inList
不起作用。
理论上,Criteria的eqAll()
或HQL = ALL
可行。 但是,我不确定,因为我无法让任何一个人工作。
使用inList
返回Urls
的子集:包含至少一个UrlIndication
ID的子集将起作用。然后使用Groovy的containsAll()
完成工作。
def ids = indicationsId.collect { UUID.fromString(it as String) }
Url.createCriteria()
.buildCriteria {
indications {
inList 'id', ids
}
}
.setResultTransformer(org.hibernate.Criteria.DISTINCT_ROOT_ENTITY)
.list()
.findAll {
it.indications.id.containsAll(ids)
}
由于查询可能会返回重复的Url
个实例,因此ResultTransformer
设置为返回唯一列表。
最后,findAll()
与containsAll()
一起用于进一步过滤列表。
以下内容可能有效。 Grails的HibernateCriteriaBuilder正在进行一些时髦的事情,它导致eqAll方法在根实体中查找属性;完全忽略了子标准。所以下面直接使用Hibernate。它不适合我,但它尽可能接近我。它给了我一个头痛!
Url.createCriteria().buildCriteria {}
.createCriteria('indications', 'i')
.add(org.hibernate.criterion.Property.forName('i.id').eqAll(org.hibernate.criterion.DetachedCriteria.forClass(UrlIndication)
.add(org.hibernate.criterion.Restrictions.in('id', ids))
.setProjection(org.hibernate.criterion.Property.forName('id'))
))
.setResultTransformer(org.hibernate.Criteria.DISTINCT_ROOT_ENTITY)
.list()
我遇到的问题是我无法让Restrictions.in
工作。 Restrictions.eq
工作正常。
答案 1 :(得分:0)
in
子句应该:
indications {
'in' 'id', indicationsId.collect{ UUID.fromString indication.toString() }
}