我们最近遇到了 JPA 和 @ManyToOne / @OneToMany 关系查询的问题,导致堆栈溢出。但这仅在创建实体后重新启动应用程序服务器时发生
问题:当我通常启动我的应用程序服务器并部署我的战争文件时,我可以用一些内容填充我的数据库并无论如何查询它。但是,当我在不清除数据库的情况下重新启动服务器并尝试执行相同的查询时,会出现奇怪的行为:
我得到一个 Stackoverflow 异常:
java.lang.StackOverflowError
at java.lang.StringBuffer.append(StringBuffer.java:224)
at java.io.StringWriter.write(StringWriter.java:84)
at java.io.StringWriter.append(StringWriter.java:126)
at java.io.StringWriter.append(StringWriter.java:24)
at com.google.gson.stream.JsonWriter.beforeValue(JsonWriter.java:610)
at com.google.gson.stream.JsonWriter.open(JsonWriter.java:317)
at com.google.gson.stream.JsonWriter.beginObject(JsonWriter.java:300)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.write(ReflectiveTypeAdapterFactory.java:190)
at com.google.gson.Gson$FutureTypeAdapter.write(Gson.java:879)
at com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.write(TypeAdapterRuntimeTypeWrapper.java:68)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.write(ReflectiveTypeAdapterFactory.java:89)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.write(ReflectiveTypeAdapterFactory.java:195)
[...]
为了完整起见:我的实体具有以下关系:
任务实体:
@OneToMany(mappedBy = "mission", cascade=CascadeType.ALL)
private Collection<Mission2Mission> children;
@OneToMany(mappedBy = "parent", cascade=CascadeType.ALL)
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
private Collection<Mission2Mission> parents;
Mission2Mission 实体:
@ManyToOne
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
private Mission parent;
@ManyToOne
private Mission mission;
这意味着,父母知道他们的孩子,反之亦然,但至少应该通过使用保留策略来避免典型的 GSON Stackoverflow,因为父母被排除在外。
我不知道这整个问题是否与 JPA 或 GSON 有关,但真正让我想知道的是,为什么这只会在服务器重新启动后发生。它表示某种会话问题,我无法弄清楚,我还没有找到关于这个特定问题的任何其他线程或问题,所以我就在这里问一下。
我知道有惰性和急切的获取类型,但使用它们并不能解释为什么这个问题只在服务器重新启动时出现。
非常感谢,凯