为了账号安全,请及时绑定邮箱和手机立即绑定

休眠中的自引用实体导致 StackOverflowErrors

休眠中的自引用实体导致 StackOverflowErrors

牛魔王的故事 2021-07-17 18:05:57
在我的一个 Java 实体 (MyState) 中,我有一个对自身的引用。注释如下所示:@OneToOne @JoinColumn(name = "previousStateId", nullable = true,         foreignKey = @ForeignKey(name = "fk_state_previousstate"))private MyState previousState;这曾经工作得很好,直到表格变大并且越来越多的状态相互指向。现在,当我尝试获取最新的 MyState 时,会发生 StackOverflowError,因为嵌套太深。有什么比这里更好的网站来问我的问题?;-)我最终需要访问根状态(一长串状态中的第一个状态),以及前一个状态。有什么办法可以避免获得所有参考资料?我试图添加一个指向原始状态的新字段“rootState”。这当然是 2 个状态的短链,所以效果很好。但是,我确实也需要以前的状态。我应该尝试通过将 previousState 的 previousState 设置为 null 来手动中断链,还是有更好的选择?
查看完整描述

2 回答

?
天涯尽头无女友

TA贡献1831条经验 获得超9个赞

显然这是一个错误。如果您有一个实体 Person 并且该实体具有对另一个 Person 的嵌套引用,则意味着嵌套的 Person 具有另一个嵌套链接,因此它会执行子嵌套链接,依此类推。您不必使用 Person 对象引用嵌套的 Person。改用唯一的 id。


public class Person{

    private int idNestedPerson;

    //fields + getters/setters

}

现在您有 2 个选择:使用外键或保持原样。如果您选择第一个选项,您必须映射该nestedId,但我建议您开始使用第二个选项。这样你就有一个带有引用“父亲”人的 id 的人。如果该 nestedId 为 != null OR > 0(根据您分配给 id 的类型),则表示 Person 是嵌套的,如果未填充 id 或 id 的默认 int 值为 0,则表示 Person是一个“根”,所以不是嵌套的。有关详细信息,请参阅“分层数据”。


查看完整回答
反对 回复 2021-07-22
?
www说

TA贡献1775条经验 获得超8个赞

这应该有效,直到您有循环依赖。对于循环依赖,StackOverflowError 可能会因为无限循环递归获取先前状态而发生。

例如,当你有两个实体 A 和 B。A 指向 B 而 B 指向 A 那么你有无限循环,并且使用 EAGER 获取策略你最终会得到 StackOverflowError。

您需要检查您在 DB 中是否没有任何循环依赖。


查看完整回答
反对 回复 2021-07-22
  • 2 回答
  • 0 关注
  • 169 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信