Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/jpa/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
JPA多人与日食&;GSON循环引用导致服务器重新启动后堆栈溢出_Jpa_Reference_Gson_Many To Many_Circular Reference - Fatal编程技术网

JPA多人与日食&;GSON循环引用导致服务器重新启动后堆栈溢出

JPA多人与日食&;GSON循环引用导致服务器重新启动后堆栈溢出,jpa,reference,gson,many-to-many,circular-reference,Jpa,Reference,Gson,Many To Many,Circular Reference,我有一个问题与许多双向JPA映射,这是造成我的堆栈溢出错误 虽然我的应用程序中总共有5个实体,但我相信这个问题只与其中的2个有关,为了简单起见,下面将对其中的2个进行描述 实体: 应用 使用者 一个应用程序可以有许多开发人员 用户可以开发许多应用程序 以下是它们的映射方式: //应用实体: @ManyToMany private List<Users> users 用户 身份证件 一, 现在,当服务器停止并重新启动时,或者当应用程序使用createtables重新部署时 (vs d

我有一个问题与许多双向JPA映射,这是造成我的堆栈溢出错误 虽然我的应用程序中总共有5个实体,但我相信这个问题只与其中的2个有关,为了简单起见,下面将对其中的2个进行描述

实体:

应用

使用者

一个应用程序可以有许多开发人员

用户可以开发许多应用程序

以下是它们的映射方式:

//应用实体:

@ManyToMany
private List<Users> users
用户
身份证件 一,

现在,当服务器停止并重新启动时,或者当应用程序使用createtables重新部署时 (vs drop和create tables)(数据存在于表中)然后我在每个entities toString()函数中得到一个堆栈溢出。 我在debug中使用断点在Applications toString()函数和Users toString()函数上运行了这个函数,我可以单击resume并观察每个toString()函数被反复调用,直到 导致堆栈溢出

以下是控制台日志:

(正在执行实体查询)

【EL Fine】:2014-01-21 14:48:44.383--服务器会话(1615948530)--连接(49767657)--线程(线程[http-bio-8080-exec-9,5,main])--选择 t1.ID,t1.APPIDENTIFIER,t1.DATECREATED,t1.DATEMODIFIED, t1.DEVICETYPE来自应用程序\用户t0,应用程序t1,其中 ((t0.users\u ID=?)和(t1.ID=t0.applications\u ID))

(调用第二个实体查询)

【EL Fine】:2014-01-21 14:50:02.444--服务器会话(1615948530)--连接(1871047709)--线程(线程[http-bio-8080-exec-9,5,main])--选择 t1.ID,t1.DATECREATED,t1.DATEMODIFIED,t1.EMAIL,t1.FIRSTNAME, t1.FULLNAME,t1.lastloginandate,t1.LASTNAME,t1.USERNAME FROM 应用程序用户t0、用户t1,其中((t0.APPLICATIONS\U ID=?)和 (t1.ID=t0.users\u ID))

[EL Finest]:2014-01-21 14:50:02.471——服务器会话(1615948530)——连接(1601422824)——线程(线程[http-bio-8080-exec-9,5,main])——连接 已释放到连接池[读取]

java.lang.StackOverflower错误

   at java.util.Vector.get(Vector.java:693)

   at java.util.AbstractList$Itr.next(AbstractList.java:345)

   at java.util.AbstractCollection.toString(AbstractCollection.java:421)

   at java.util.Vector.toString(Vector.java:940)

   at org.eclipse.persistence.indirection.IndirectList.toString(IndirectList.java:797)

   at java.lang.String.valueOf(String.java:2826)

   at java.lang.StringBuilder.append(StringBuilder.java:115)

   at com.sap.crashlogserver.dao.entities.Applications.toString(Applications.java:150)

   at java.lang.String.valueOf(String.java:2826)

   at java.lang.StringBuilder.append(StringBuilder.java:115)

   at java.util.AbstractCollection.toString(AbstractCollection.java:422)

   at java.util.Vector.toString(Vector.java:940)

   at org.eclipse.persistence.indirection.IndirectList.toString(IndirectList.java:797)

   at java.lang.String.valueOf(String.java:2826)

   at java.lang.StringBuilder.append(StringBuilder.java:115)

   at com.sap.crashlogserver.dao.entities.Users.toString(Users.java:168)

   at java.lang.String.valueOf(String.java:2826)

   at java.lang.StringBuilder.append(StringBuilder.java:115)

   at java.util.AbstractCollection.toString(AbstractCollection.java:422)

   at java.util.Vector.toString(Vector.java:940)

   at org.eclipse.persistence.indirection.IndirectList.toString(IndirectList.java:797)

   at java.lang.String.valueOf(String.java:2826)

   at java.lang.StringBuilder.append(StringBuilder.java:115)

   at com.sap.crashlogserver.dao.entities.Applications.toString(Applications.java:150)

   at java.lang.String.valueOf(String.java:2826)

   at java.lang.StringBuilder.append(StringBuilder.java:115)

   at java.util.AbstractCollection.toString(AbstractCollection.java:422)

   at java.util.Vector.toString(Vector.java:940)
根据我读到的大量线程,我尝试: 1.颠倒映射, 2.将@JsonIgnore添加到某些实体字段 3.使用fetch=FetchType.LAZY

还有许多其他的配置调整,但都没有解决这个问题。 一些建议像使用瞬态场。我不确定我的JPA eclipselink实现是否支持这一点

我还阅读了一篇帖子,建议我实施gson.ExclusionStrategy。 我还没有试过这个

这就是故事。我是Java和JPA的新手。 这对我来说是一个很难解决的问题。
如果您有任何建议可以帮助我解决此问题,我们将不胜感激。

您的objects-toString方法正在对整个模型递归调用toString。堆栈没有显示最初调用它的原因,但可能是由于某些日志记录设置。修复您的toString方法并关闭日志记录,

也许这会对某人有所帮助

我也有同样的问题。我使用注释
@InvisibleJson
和自定义
排除策略来隐藏这些字段

public class SafeDataExclusionStrategy implements ExclusionStrategy {

    @Override
    public boolean shouldSkipClass(Class<?> c) {
        return false;
    }

    @Override
    public boolean shouldSkipField(FieldAttributes c) {
        return c.getAnnotation(InvisibleJson.class) != null;
    }

}

@InvisibleJson
@许多(mappedBy=“角色”)
公开名单工作人员;

所以GSON不会在staff对象内部挖掘。

非常简单的解决方案,在所有希望GSON序列化/反序列化的变量和列表上使用注释
@Expose

一个基本上只允许GSON使用名称的简单示例:

@Expose
private String name;

@ManyToMany
private List<Users> users 
@Expose
私有字符串名称;
@许多
私有列表用户
然后,在使用GsonBuilder的地方,执行以下操作:

GsonBuilder builder = new GsonBuilder().disableHtmlEscaping();
builder.excludeFieldsWithoutExposeAnnotation();  //<-- This tells GSON look for @Expose
gson = builder.create();
GsonBuilder=new GsonBuilder().disableHtmlEscaping();

builder.excludeFieldswithout exposeannotation()//修复toString方法是什么意思?这是它的外观:return“User[id=“+id+”,userName=“+userName+”,email=“+email+”,fullName=“+fullName+”,firstName=“+firstName+”,lastName=“+lastName+”,lastLoginDate=“+lastLoginDate+”,applications=“+applications+”); 通过将对象中的对象转换为字符串,您实际上也在对它们调用toString,这最终会对它们的引用等调用toString。您的toString方法实现需要修复-只打印出对象的字符串版本中使用的Primative。尤其要避免不必要地打印收藏。打印集合和关系触发器加载它们(如果它们是惰性的)。
@Retention(RetentionPolicy.RUNTIME)
@Target(value = ElementType.FIELD)
public @interface InvisibleJson {}
@InvisibleJson
@ManyToMany(mappedBy="roles")
public List<Staff> staff;
@Expose
private String name;

@ManyToMany
private List<Users> users 
GsonBuilder builder = new GsonBuilder().disableHtmlEscaping();
builder.excludeFieldsWithoutExposeAnnotation();  //<-- This tells GSON look for @Expose
gson = builder.create();