Grails GORM JOIN在查询中

时间:2014-04-25 21:47:38

标签: hibernate grails gorm

我有一个实体,它是NotificationUser之间的联接实体:

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的这种行为吗?

2 个答案:

答案 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对象)。