我有一个实体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=?
为什么刷新加入收件人但查找查询不是?
答案 0 :(得分:1)
供参考:
将大型集合映射到具有hasMany / belongsTo的域通常是有问题的,因为大多数操作都级联到集合。这就是为什么在您的情况下刷新收件人的原因,但在该域名的其他业务代码中可能会出现类似的问题。
这不是特定于GORM的(虽然级联是由GORM自动设置的),因为这些类型的嵌入式集合将在纯Hibernate / Java代码中进行类似的映射。
在这种情况下,最好将收件人与Campaign分开,而在Campaign中根本没有嵌入式收藏。
您也可以尝试手动为收件人集合定义级联(特别是省略刷新)