各位,请帮我解决以下问题。
我遇到了著名的“无法同时获取多个包”错误,因为我的父实体中有两个列表。这是一段代码:
class Manager{
@OneToMany(cascade = CascadeType.ALL)
@Fetch(FetchMode.JOIN)
@IndexColumn(name = "id")
private List<Action> actions;
@OneToMany(cascade = CascadeType.ALL)
@Fetch(FetchMode.JOIN)
@IndexColumn(name = "id")
private List<Activity> activities;
(...)
}
映射是单向的。
好的,我在谷歌上搜索到可以使用 IndexColumn 注释来修复它。正如您所看到的,我已经实现了这一点,现在我没有得到提到的异常。但问题是,现在如果我想从数据库获取所有管理器,我会收到更多真正存在的管理器实例!
例如,如果每个集合中只有 1 个管理器和 3 个子实例,则有 9 个管理器实例。我可以理解为什么会发生这种情况:Hibernate 生成一个看起来像这样的选择
select ... from Manager this_
left outer join manager_action actions3_ on this_.id=actions3_.Manager_id
left outer join Action action4_ on actions3_.actions_id=action4_.id
left outer join Manager_Activity activities5_ on this_.id=activities5_.Manager_id
left outer join Activity activity6_ on activities5_.activities_id=activity6_.id
...它确实获取了比一行更多的行。
为什么会发生这种情况? 我该如何修复它?
最佳答案
Hibernate 生成笛卡尔积,并且在这种情况下不会进行重复数据删除。像这样的笛卡尔积(3 个操作 * 3 个 Activity = 9 行)仅适用于集合而不是列表。
即使有两个集合,您也应该避免这些类型的笛卡尔积。想一想:仅检索一位具有 100 个操作和 100 个 Activity 的经理就会从数据库中检索 10,000 行。您也许应该提出两个查询:
- 获取管理器及其操作(100 行)
- 获取同一管理器及其 Activity (100 行)
这只会产生 200 行,而不是 10,000 行。结果将是相同的,因为 Activity 将附加到 session 中的同一个 Manager 实例。它还可以避免您遇到的重复问题。
关于java - 无法获取多个包 : why @IndexColumn returns wrong results?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8075853/