猿问

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

在我的一个 Java 实体 (MyState) 中,我有一个对自身的引用。注释如下所示:

@OneToOne
@JoinColumn(name = "previousStateId", nullable = true,
        foreignKey = @ForeignKey(name = "fk_state_previousstate"))private MyState previousState;

这曾经工作得很好,直到表格变大并且越来越多的状态相互指向。现在,当我尝试获取最新的 MyState 时,会发生 StackOverflowError,因为嵌套太深。有什么比这里更好的网站来问我的问题?;-)

我最终需要访问根状态(一长串状态中的第一个状态),以及前一个状态。

有什么办法可以避免获得所有参考资料?我试图添加一个指向原始状态的新字段“rootState”。这当然是 2 个状态的短链,所以效果很好。

但是,我确实也需要以前的状态。我应该尝试通过将 previousState 的 previousState 设置为 null 来手动中断链,还是有更好的选择?


牛魔王的故事
浏览 170回答 2
2回答

天涯尽头无女友

显然这是一个错误。如果您有一个实体 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是一个“根”,所以不是嵌套的。有关详细信息,请参阅“分层数据”。

www说

这应该有效,直到您有循环依赖。对于循环依赖,StackOverflowError 可能会因为无限循环递归获取先前状态而发生。例如,当你有两个实体 A 和 B。A 指向 B 而 B 指向 A 那么你有无限循环,并且使用 EAGER 获取策略你最终会得到 StackOverflowError。您需要检查您在 DB 中是否没有任何循环依赖。
随时随地看视频慕课网APP

相关分类

Java
我要回答