【发布时间】:2014-09-01 21:08:17
【问题描述】:
我是一个相当新的 Grails 用户,我正在努力使用 GORM 设置进行一些更复杂的查询。
我有两个域对象/表,LOCATION 和 REASON,它们具有多对多映射,由 LOCATION_REASON 表管理:
Location.groovy:
class Location {
String description
// other fields
static hasMany = [reasons: Reason]
static mapping = {
sort description:"asc"
id generator:'native', params:[sequence:'ATTENDANCE_TRACKER.ID_SEQ']
reasons joinTable: [name: 'LOCATION_REASON', key: 'LOCATION_ID', column: 'REASON_ID'], cascade: 'none'
}
static namedQueries = {
findAllWhereReasonIsNot { reasonId ->
reasons { ne('id', reasonId) }
}
}
//Other stuff
}
Reason.groovy:
class Reason {
String description
//other fields
static hasMany = [locations: Location]
static mapping = {
id generator:'native', params:[sequence:'ATTENDANCE_TRACKER.ID_SEQ']
locations joinTable: [name: 'LOCATION_REASON', key: 'REASON_ID', column: 'LOCATION_ID'], cascade: 'none'
}
//Other stuff
}
命名查询 'findAllWhereReasonIsNot' 没有像我希望的那样运行。我想要一个查询来完成获取尚未与指定原因关联的所有位置。
在 SQL 术语中,我想要这个:
select * from location where id not in(select location_id from location_reason where reason_id = :reasonId);
但是一旦生成了休眠 SQL,当前实现正在完成的工作看起来或多或少(编辑为仅包含相关信息,并具有合理的“选择为”名称):
select * from
(
select
this_.id as loc_location_id,
this_.description as location_description,
reasons3_.LOCATION_ID as loc_reas_location_id,
reasons3_.REASON_ID as loc_reas_reason_id,
reasons_al1_.id as reas_reason_id,
reasons_al1_.description as reason_description
from location this_
inner join location_reason reasons3_ on this_.id=reasons3_.LOCATION_ID
inner join reason reasons_al1_ on reasons3_.REASON_ID=reasons_al1_.id
where (reasons_al1_.id <> :reasonId)
order by lower(this_.description) asc
);
这会生成一个包含每个位置的多个副本的列表,每个副本对应于与其相关的每个原因。这可以防止结果列表实际上排除与原始 reasonId 关联的位置,因为其他原因与该位置相关联。
我对 Criteria 和 HQL 进行了一些研究,但无法生成有效的查询...似乎 Criteria 和 HQL 有一些限制,所以我什至不确定它是否可能。有谁知道如何在命名查询中完成那个简单的“不在”子查询?
【问题讨论】:
标签: hibernate grails many-to-many subquery grails-orm