java - 解决递归关系中的 StackOverflow 异常

标签 java json

我在实体之间有递归关系,目前我的 REST API 将其转换为 JSON,我得到了一个 StackOverflow 异常,我完全理解这一点。

Jersey 使用 yasson 作为默认 JSON 提供程序,我找到了一个解决方案,您可以在序列化时使用 @JsonbTransient 忽略对象中的属性。我的用户类有一个推文列表,一条推文有一个用户。因此,我将 @JsonbTransient 添加到 User 类中的推文列表属性中。

用户级别:

public class User {
    ...
    @JsonbTransient
    @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
    @JoinColumn(name = "user_id")
    private List<Tweet> tweets;
    ...
}

推文类别:

public class Tweet {
    ...
    @ManyToOne
    private User user;
    ...
}

我想在访问相关用户的一些属性时呈现所有推文(来自不同用户)的列表。但我想在同一页面上向用户呈现他的推文列表(用于获取推文计数等)。忽略用户类上的推文列表是不够的。

是否还有一个注释提供了一种序列化此类关系的方法,而无需完全忽略第一级的属性,而是在更深的级别上。

例如:当您知道自己位于有用户的 Tweet 对象中时,该用户将忽略他的推文列表,而当用户不在推文对象中时,他的推文列表将不会被忽略。或者这根本不可能?

有人会如何解决这样的问题?

我当然可以忽略用户中的推文列表属性,当我想要相应用户的推文时,我可以在另一个调用中检索它们。 (不要与延迟加载混淆,因为我想要开始时的数据)

但我的想法是,可能有一个神奇的注释可以自动解决这个问题。在那里吗?

提前致谢,

迈克

最佳答案

您将 API 模型与数据库模型绑定(bind)得太紧密。不要这样做。

您的 API 想要返回一个包含根用户对象的模型,其中包含详细信息,包括推文列表,并且推文想要识别用户,但不想要完整详细的用户对象,即它只需要一个用户引用。

示例:

{
  "UserId": 1,
  "UserName": "Bob",
  "UserEmail": "bib@example.com",
  "Tweets": [
    {
      "User": {
        "UserId": 2,
        "UserName": "Alice",
      },
      "Text": "Hello Bob"
  ]
}

如您所见,内部用户对象是 MiniUser,外部用户对象是 FullUser (任意名称,您可能想要调用它们为其他名称)

因此,从 DAO 模型创建 API 模型。不要让 DAO 模型成为 API 模型。

关于java - 解决递归关系中的 StackOverflow 异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56203451/

相关文章:

java -/mnt/sdcard/Android/data 文件夹(或同等文件夹)是否存在于出厂时的所有硬件设备中?

java - 我的 Ubuntu 安装上的 Java 版本是 "1.8.0_191"?

java - 强制子类定义 protected 最终实例变量

java - Netty 聊天服务器出现问题

javascript - 在同一个 Chrome 应用程序窗口中打开 HTML 文件?

php - 你如何将 php 结果填充到 jquery 移动 ListView 中

java - 如何迭代 Java 枚举?

javascript - 为什么我收到有关 "unexpected non-whitespace after JSON data"的错误消息

android - "failure in processEncodedAnnotation"在 Android 上使用 Jackson 和 ScalaModule

javascript - 如何使用 Ajax 将 WebSocket 数据从 View 发送到 Controller 以及将修改后的数据发送到 View