jpa oneToMany和jackson序列化问题(新手)

Posted

技术标签:

【中文标题】jpa oneToMany和jackson序列化问题(新手)【英文标题】:jpa oneToMany and jackson serialization problems (newbie) 【发布时间】:2020-09-25 01:02:36 【问题描述】:

我不太清楚如何为这个问题命名,所以如果需要,请随时编辑。

我是 jpa/spring 的新手,我发现了一个我认为应该很常见的问题,但我找不到任何合理的答案。

我正在使用 springboot 创建一个 RestAPI。这个 API 有 2 个端点 (GET) /user(GET) /address ,它们以 1:1 的比例映射到我的数据库中的实体。它们之间的关系是1:N,通过user_id加入。

我的想法是,根据调用的端点,返回完全填充的实体(用户的地址或用户填充的地址列表)。

我尝试使用 jpa annotations OneToMany/ManyToOne 所以hibernate 会自动解决这个问题,但在这种情况下,我还需要用 Jackson 注释来注释字段,这些字段是静态的,会破坏我的一个端点. (我可以获取用户的地址,或者用户的地址,但不能同时获取)

我发现的选项 b) 是打破关系并将 ID 留在实体中,并将​​完整对象设置为瞬态,然后在代码中填充。对于 manyToOne 关系来说很容易进行映射,但对于 OneToMany 来说并不容易,因为我必须获取所有地址、所有用户并通过代码进行映射。我希望有大量的用户和地址,所以这可能很昂贵。

对此的另一种可能的解决方案,但我还没有找到如何在控制器中序列化为 json 时将递归限制为 1 级,但我没有看到如何做到这一点。

也可以通过使用自定义 jql/sql 查询填充具有标准连接的瞬态字段来完成。

对于给出的示例,让我们假设表格如下所示:

User:
 - id: long autoincrement (PK)
 - name: varchar(255)

Address:
 - id long autoincrement (PK)
 - user_id long,
 - street varchar(255)

非常感谢,很抱歉这么大的文字

【问题讨论】:

【参考方案1】:

最后我找到了一种不那么肮脏的方法来实现这一点。

我为每个实例创建了一个接口,但没有创建用于创建 Jackson 序列化类的循环引用的方法。

在实体的属性上使用@JsonSerialize(as=MyInterface.class) 使其递归(用户中的地址和地址中的用户)

通过这种方式,同时您在 json 中保持 1 个深度级别,您可以实现类的“动态”序列化

【讨论】:

以上是关于jpa oneToMany和jackson序列化问题(新手)的主要内容,如果未能解决你的问题,请参考以下文章

Jackson 在序列化时触发 JPA Lazy Fetching

Jackson 未对 JPA id 字段进行序列化

Spring Boot 2. Jackson json 序列化或 Spring Data JPA FetchType.Lazy

JPA、OneToMany 和 ManyToOne

不加入子表的 JPA (@OneToMany) 查询

使用杰克逊将双向 JPA 实体序列化为 JSON