我有一个实体,它是Notification
和User
之间的联接实体:
class NotificationRecipient implements Serializable {
Notification notification
User recipientUser
static mapping = {
table 'notification_recipient'
version false
notification cascade: 'all'
recipientUser cascade: 'all'
id generator: 'assigned', composite: ['notification', 'recipientUser']
}
}
我想创建接收分配给指定用户的所有通知的查询,但是我希望填充notification
字段以避免在迭代结果时进行N + 1选择(1个查询用于检索列表和1个选择每个每个通知字段访问使用默认延迟加载)如使用Eager Fetching查询部分中所述http://grails.org/doc/2.3.7/guide/single.html#criteria。
我不想更改mapping
并将notification
设置为lazy: false
,但请在查询(http://grails.org/doc/2.3.7/guide/single.html#fetchingDSL)中指定。
我的查询是(正如文档所说):
def resut = NotificationRecipient.createCriteria().list(options?.params ?: [:]) {
eq("recipientUser.id", userId)
join 'notification'
}
但仍会生成N + 1个查询。
我也尝试过设置获取模式:
NotificationRecipient.createCriteria().list(options?.params ?: [:]) {
eq("recipientUser.id", userId)
fetchMode "notification", FetchMode.JOIN
}
没有成功。
你能解释一下Grails的这种行为吗?
答案 0 :(得分:1)
不幸的是,这是一个Hibernate或Grails的错误:
http://jira.grails.org/browse/GRAILS-9285
解决方案是删除复合主键id generator: 'assigned', composite: ['notification', 'recipientUser']
。
对于compoun主键连接不起作用。订购依据也不正常。
答案 1 :(得分:0)
您是否尝试过使用:
NotificationRecipient.findAllByRecepientUser(user, [fetch:[notification:'eager']])
类似的请求在我的系统上运行良好(没有N + 1)。
我还会检查Notification上是否存在延迟获取的参数(通知是急切加载的,但通知中的某些属性不是简单类型,而是需要延迟加载的Domain对象)。