Java 导出为json时生成的数据库实体的循环依赖关系

Java 导出为json时生成的数据库实体的循环依赖关系,java,mysql,json,jpa,Java,Mysql,Json,Jpa,我有一个像这样的数据库 除了配方表外,所有表都有 recipe_id int not null, foreign key (recipe_id) references recipes(id) 我使用eclipse中的JPA工具自动生成实体,但不是外键recipe\u id //bi-directional many-to-one association to Recipe @ManyToOne private Recipe recipe; 例如,当我尝试将我所有的食谱导出为json格式时,

我有一个像这样的数据库

除了
配方
表外,所有表都有

recipe_id int not null, foreign key (recipe_id) references recipes(id)
我使用eclipse中的JPA工具自动生成实体,但不是外键
recipe\u id

//bi-directional many-to-one association to Recipe
@ManyToOne
private Recipe recipe;
例如,当我尝试将我所有的食谱导出为json格式时,我会得到一个stackoverflow异常,这是因为当它写入json时,它会访问过敏原,我的过敏原类有一个Recipe对象(指向包含这些特定过敏原的食谱),所以它会再次写入该Recipe对象,以此类推

另外,当我试图简单地打印出一个配方时,我得到了以下输出,考虑到我从mysql添加数据时所有外键都设置正确

allergens={IndirectList: not instantiated}, ingredients={IndirectList: not instantiated}, mediaitems={IndirectList: not instantiated}, nutritionvalues={IndirectList: not instantiated}, steps={IndirectList: not instantiated}
我希望这是有道理的


你知道怎么解决这个问题吗

导出到json试图将java bean序列化为文本形式。在java中,具有双向关联(如配方和mediaitem之间的关联)是非常常见和有用的。这两个对象都相互引用。然而,这种循环关联不能用json或任何文本形式表示,因为它们本质上是扁平的树状结构

大多数json封送器的工作方式是,它们检查应该序列化的对象实例,并迭代其所有可访问的属性。对于每个属性,封送拆收器将再次以递归方式调用函数。因此,如果您有循环关联,递归将永远继续,直到jvm耗尽堆栈内存,因此出现stwckOverflowException

由于这是一个常见问题,有几种解决方案可用。一些json LIB支持循环检测,当它们发现与堆栈中已经存在的对象的循环关联时,它们不会再次尝试对其进行封送—相反,它会被忽略,或者只打印它的Id。例如,看一看


另一种策略是将数据模型与json模型分离,通常称为DTO映射。在本例中,您创建了一组与实体类似的新pojo类,并具有某种beanmapper,将实体映射到DTO,反之亦然。这样,在将数据提交给json序列化程序之前,您可以控制关联并删除任何周期。

导出到json试图将java bean序列化为文本形式。在java中,具有双向关联(如配方和mediaitem之间的关联)是非常常见和有用的。这两个对象都相互引用。然而,这种循环关联不能用json或任何文本形式表示,因为它们本质上是扁平的树状结构

大多数json封送器的工作方式是,它们检查应该序列化的对象实例,并迭代其所有可访问的属性。对于每个属性,封送拆收器将再次以递归方式调用函数。因此,如果您有循环关联,递归将永远继续,直到jvm耗尽堆栈内存,因此出现stwckOverflowException

由于这是一个常见问题,有几种解决方案可用。一些json LIB支持循环检测,当它们发现与堆栈中已经存在的对象的循环关联时,它们不会再次尝试对其进行封送—相反,它会被忽略,或者只打印它的Id。例如,看一看


另一种策略是将数据模型与json模型分离,通常称为DTO映射。在本例中,您创建了一组与实体类似的新pojo类,并具有某种beanmapper,将实体映射到DTO,反之亦然。这样,在将数据提交给json序列化程序之前,您可以控制关联并删除任何循环。

我认为,当您尝试在json中导出无限嵌套的变量时,会发生此类错误。。。我不知道这是否合理。。但就像你可以做你的var.List.Table.List.Table.List.List…恐怕我不明白你的意思,就像你说的“…所以它再写一次配方对象,永远如此”。我不知道如果没有链接到每个表,为什么每个表中都会有配方id。。我知道菜谱是主表,但我不确定营养价值是什么,它只是另一个表,有一个外键菜谱。我知道图表的外观,表看起来很特别,但实际上并不是。我认为当您尝试在json中导出无限嵌套的变量时,会发生这样的错误。。。我不知道这是否合理。。但就像你可以做你的var.List.Table.List.Table.List.List…恐怕我不明白你的意思,就像你说的“…所以它再写一次配方对象,永远如此”。我不知道如果没有链接到每个表,为什么每个表中都会有配方id。。我知道菜谱是主表,但我不确定营养价值是什么,它只是另一个表,有一个外键菜谱。我知道图表的样子,那张桌子看起来很特别,但其实没什么。谢谢你的回复。因此,我对
配方
类中的数组使用了
@JsonBackReference
,对其他类中的配方对象使用了
@JsonManagedReference
,但出于某种原因,我仍然会得到堆栈溢出。我遗漏了什么吗?还在每个类的顶部尝试了
@JsonIdentityInfo(generator=ObjectIdGenerators.IntSequenceGenerator.class,property=“@id”)
,幸运的是,为了避免堆栈溢出exc,您不需要处理所有的双向关联。另外,您确定使用Jackson作为封送员吗(例如,您使用的是什么服务器或库)?您好,非常感谢您的回复。因此,我对
配方
类中的数组使用了
@JsonBackReference
,对其他类中的配方对象使用了
@JsonManagedReference
,但出于某种原因,我仍然得到了