【问题标题】:Grails GORM JOIN in query查询中的 Grails GORM JOIN
【发布时间】:2014-04-25 21:47:38
【问题描述】:

我有一个实体,它是 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 个查询用于检索列表,每个通知一个选择使用默认延迟加载的字段访问),如 Querying with 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 的这种行为吗?

【问题讨论】:

    标签: hibernate grails grails-orm


    【解决方案1】:

    不幸的是,这是一个 Hibernate 或 Grails 错误:

    http://jira.grails.org/browse/GRAILS-9285

    解决方法是删除复合主键id generator: 'assigned', composite: ['notification', 'recipientUser']

    对于复合主键连接不起作用。此外,order by 也无法正常工作。

    【讨论】:

      【解决方案2】:

      您是否尝试过使用:

      NotificationRecipient.findAllByRecepientUser(user, [fetch:[notification:'eager']])
      

      类似的请求在我的系统上效果很好(没有 N+1)。

      我还会检查 Notification 上是否有延迟获取的参数(Notification 是急切加载的,但是通知中的某些属性不是简单类型,而是需要延迟加载的域对象)。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-06-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多