Grails GORM刷新忽略了获取策略

时间:2013-09-25 23:10:10

标签: hibernate grails gorm

我有一个实体Campaign,它与Contact使用联接表Recipient具有多对多关系。

class Campaign {
    ...
    static hasMany = [recipients: Recipient]
    ...
}

class Recipient {
    ...
    Contact contact
    static belongsTo = [campaign: Campaign]
    ...
}

class Contact {
    ...
}

广告系列可以拥有数十万个联系人,但由于懒惰提取是默认设置,因此可以快速从数据库中检索广告系列。但是,当我调用campaign.refresh() GORM尝试加载所有收件人时,Grails内存不足。

List<Campaign> campaigns = Campaign.findAllWhere([status: CampaignStatus.STARTED])
campaigns.each { campaign ->
    if (campaign.refresh().isStarted()) {
        campaign.send();
    }
}

我打开logSql,看看正在执行什么。此代码已被清理以便于阅读。

-- Campaign.findAllWhere
select * from campaign where (status=?)

-- campaign.refresh()
select * from campaign c left outer join recipient r on c.campaign_id=r.campaign_id where c.campaign_id=?

为什么刷新加入收件人但查找查询不是?

1 个答案:

答案 0 :(得分:1)

供参考:

将大型集合映射到具有hasMany / belongsTo的域通常是有问题的,因为大多数操作都级联到集合。这就是为什么在您的情况下刷新收件人的原因,但在该域名的其他业务代码中可能会出现类似的问题。

这不是特定于GORM的(虽然级联是由GORM自动设置的),因为这些类型的嵌入式集合将在纯Hibernate / Java代码中进行类似的映射。

在这种情况下,最好将收件人与Campaign分开,而在Campaign中根本没有嵌入式收藏。

您也可以尝试手动为收件人集合定义级联(特别是省略刷新)