我正在尝试构建一个我称为组的类的层次结构。域名非常简单:
class SubGroup implements Serializable {
Group child
Group parent
static mapping = {
id composite: ['child', 'parent']
}
}
class Group implements Serializable {
int groupId
String key
String title
static mapping = {
id name: 'groupId'
}
}
基本上我想建立一个群组父母及其相关孩子的地图。所以我循环遍历每条记录(如果有一种更清晰的方式来查询我很高兴听到它的地图)并为它创建地图条目。
Map hierarchy = [:]
SubGroup.list().each { relation ->
if (!hierarchy[relation.parent]) {
hierarchy[relation.parent] = new HashSet()
}
hierarchy[relation.parent] << relation.child
}
我认为hibernate会使用一些简单的查询来执行这样的操作:
select * from sub_group s, group c, group p
where s.child_id = c.group_id and s.parent_id = p.group_id
但它没有进行加入。它正在对子组进行查询,然后对组表进行n次查询(N + 1选择问题)。啊。我在2.0中听说hibernate query cache存在问题所以我禁用了它。我已经尝试将 lazy:false 和 fetch:join 添加到我的SubGroup域类中,无论是父列还是子列都没有运气。我尝试将(fetch:[child:'eager'])作为参数添加到list方法中。它不会进行连接。我错过了什么吗?说实话,它实际上甚至不需要进行连接,因为我只访问groupId外键属性,虽然稍后我将需要键和标题属性。
当然,我可以创建子和父属性int并在我需要其余数据时进行自己的查询,或者我可以使用HQL和其他一些方法将此限制为单个查询,但似乎像GORM应该为我这样做。谢谢你的帮助。
的问候,
吉姆
答案 0 :(得分:0)
似乎唯一的方法是我可以让它在没有hibernate的情况下工作,为每个子节点做一个select调用,而不是使用list方法执行HQL查询,而不是使用如下所示的list方法:
Map hierarchy = [:]
def subGroups = SubGroup.executeQuery("SELECT s.parent, s.child FROM SubGroup s")
subGroups.each { relation ->
if (!hierarchy[relation[0]]) {
hierarchy[relation[0]] = new HashSet()
}
hierarchy[relation[0]] << relation[1]
}
因此我实际上只使用SubGroup域类来定义关系。我认为我应该可以通过某种映射来做到这一点,但我无法弄清楚如何。