java - 导出到 json 时生成的数据库实体的循环依赖

标签 java mysql json jpa

我有一个看起来像这样的数据库

db

除了recipe之外的所有表格都有一个

recipe_id int not null, foreign key (recipe_id) references recipes(id)

我使用 eclipse 中的 JPA 工具自动生成了我的实体,但不是外键 recipe_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 中,双向关联非常常见且有用,例如您的食谱和媒体项之间的关联。两个对象都相互引用。然而,这种循环关联不能用 json 或实际上任何文本形式表示,因为它们本质上是扁平的树状结构。

大多数 json 编码器的工作方式是检查应该被序列化的对象实例,并遍历其所有可访问的属性。对于每个属性,编码器将再次以递归方式调用该函数。因此,如果您有循环关联,递归将永远持续下去,直到 jvm 耗尽堆栈内存 - 因此会出现 stwckOverflowException。

由于这是一个常见问题,因此有多种解决方案可用。一些 json 库支持循环检测,当他们发现与堆栈中已有对象的循环关联时,他们不会尝试再次编码它——而是忽略它或只打印它的 ID。看看Jackson's backreference例如。

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

关于java - 导出到 json 时生成的数据库实体的循环依赖,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45189669/

相关文章:

java - 静态方法不在主类中运行它

java - 从 mysql 检索数据到 JTable

jquery - 从 struts2 操作返回 JSON 消息

json - Spring MVC :could not initialize proxy - no Session (through reference chain)

java - 使用 Java 配置的 Spring Hibernate JPA - 抽象方法错误

java - 在 GUI 中逐项显示数组列表

java - JButton 的颜色

mysql - 在 Kubernetes POD 中执行 MySQL 命令

mysql - 如果应用条件,则应执行查询

mysql - Laravel MySQL JSON LIKE 查询