一对多关系的Grails Criteria动态和条件
Grails Criteria dynamic AND conditions for one-to-many relationship
我有一个域名class
class Url {
UUID id
String url
static hasMany = [
indications:UrlIndication
]
...
}
和
class UrlIndication {
UUID id
String name
static belongsTo = Url
...
}
我想选择 url,以便它在给定列表 indicationsId
中包含所有必要的 UrlIndication
元素。
为此,我使用关联 and
标准,如下所示:
indications {
and {
indicationsId.each{
indication->
eq ('id',UUID.fromString(indication as String))
}
}
}
然而,我得到的只是一个空结果。你能建议任何修改/其他方法,以便我可以做到这一点吗?提前致谢
in
子句应该:
indications {
'in' 'id', indicationsId.collect{ UUID.fromString indication.toString() }
}
您的查询 return 生成了一个空列表,因为它等同于表达式(伪代码):if 1 = 1 and 1 = 2 and 1 = 3
这样的表达永远是错误的。 in
或 inList
由于@innovatism 描述的原因将不起作用。
理论上,Criteria 的 eqAll()
或 HQL 的 = ALL
会起作用。 但是,我不确定,因为我无法让任何一个工作。
有效的方法是使用 inList
到 return 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)
}
由于查询有可能 return 重复 Url
个实例,因此 ResultTransformer
设置为 return 一个唯一列表。
最后,findAll()
与 containsAll()
一起使用以进一步过滤列表。
使用 eqAll(可能)
类似下面的方法可能有效。 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
工作正常。
我有一个域名class
class Url {
UUID id
String url
static hasMany = [
indications:UrlIndication
]
...
}
和
class UrlIndication {
UUID id
String name
static belongsTo = Url
...
}
我想选择 url,以便它在给定列表 indicationsId
中包含所有必要的 UrlIndication
元素。
为此,我使用关联 and
标准,如下所示:
indications {
and {
indicationsId.each{
indication->
eq ('id',UUID.fromString(indication as String))
}
}
}
然而,我得到的只是一个空结果。你能建议任何修改/其他方法,以便我可以做到这一点吗?提前致谢
in
子句应该:
indications {
'in' 'id', indicationsId.collect{ UUID.fromString indication.toString() }
}
您的查询 return 生成了一个空列表,因为它等同于表达式(伪代码):if 1 = 1 and 1 = 2 and 1 = 3
这样的表达永远是错误的。 in
或 inList
由于@innovatism 描述的原因将不起作用。
理论上,Criteria 的 eqAll()
或 HQL 的 = ALL
会起作用。 但是,我不确定,因为我无法让任何一个工作。
有效的方法是使用 inList
到 return 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)
}
由于查询有可能 return 重复 Url
个实例,因此 ResultTransformer
设置为 return 一个唯一列表。
最后,findAll()
与 containsAll()
一起使用以进一步过滤列表。
使用 eqAll(可能)
类似下面的方法可能有效。 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
工作正常。