java - 如何通过自引用处理实体的 RESTful 响应

标签 java json rest jpa jackson

我有一个 Foo 类,它引用了它自己。
这是我遇到的情况的粗略示例。

@Entity
public class Foo() {
  @Column(name = "id", unique = true, nullable = false)
  private Long id;

  @JsonIgnore
  @ManyToOne(fetch = FetchType.LAZY)
  @JoinColumn(name = "id_Foo")
  private Foo parent;
}

当我将 Foo 对象传递给 JSON 响应生成器时,所有必需的 getter 都会被启动,并且 JPA 从 DB 检索所有必需的数据。

现在的问题是,如果我从自引用字段中删除 @JsonIgnore,我将获得父信息和父父信息等。

我想要的是我可以限制检索到的父信息的深度。
例如。:
  • Deep 0 - 我只会得到 Foo 数据
  • Deep 1 - 我将获取 Foo 和 Foo 父级的数据
  • Deep 2 - 我将获取 Foo 和 Foo 父级和 Foo 父级父级的数据

  • 也许有一个带有注释或 smth 的简单解决方案,因为我找不到任何东西。

    编辑:

    使用自定义序列化程序和一些递归魔法解决了这个问题。
    private void serializeParents(JsonGenerator gen, Foo value, int currentDepth) {
        if (currentDepth < PARENTS_DEPTH) {
          if (value.getMom() != null) {
            serializeParentData(gen, value.getMom(), currentDepth);
          }
    
          if (value.getDad() != null) {
            serializeParentData(gen, value.getDad(), currentDepth);
          }
        }
    }
    
    private void serializeParentData(JsonGenerator gen, Foo value, int currentDepth) {
        gen.writeObjectFieldStart(Gender.M.equals(value.getGender()) ? "dad" : "mom");
        // other parameters ...
        serializeParents(gen, value, currentDepth + 1);
        gen.writeEndObject();
    }
    

    最佳答案

    我认为最好的方法是创建一个自定义 DTO 对象来收集您所有的 Foo属性及其 parent ,因此您不会获得递归关系并避免延迟加载异常。

    因此,您将保持实体原样:

    @Entity
    public class Foo() {
       @Column(name = "id", unique = true, nullable = false)
       private Long id;
    
       @JsonIgnore
       @ManyToOne(fetch = FetchType.LAZY)
       @JoinColumn(name = "id_Foo")
       private Foo parent;
    }
    

    并创建一个自定义 DTO 对象,如下所示:
    public class FooDto() {
    
       private Long id;
       private Foo parent;
    
       //getters and setters here
    }
    

    然后你可以使用这个 DTO 在你的请求中存储 JSOn 结果。

    你可以看看What is the point of using DTO (Data Transfer Objects)?了解更多详情。

    @JsonIgnore文档:

    根据 jackson @JsonIgnore documentation没有这样的选项(属性)来指定注释的深度/级别,因为只有一个可能的属性 value定义此注释是否处于 Activity 状态。

    关于java - 如何通过自引用处理实体的 RESTful 响应,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42811471/

    相关文章:

    java - 使用带有 "try with resource"的 @Autowired 资源

    java - 如何在 IBatis2 中处理带有 In 子句和空 Java 列表的 SQL 语句?

    ruby-on-rails - Rails 4 不通过 JSON 更新嵌套属性

    python - 更改 Django 表单中的字段,覆盖 clean()

    json - 单元测试在 Swift 中使用 REST 调用的方法

    java - 将 MVP 模式应用于 JDialogs

    java - 使用 Google Guava 过滤和转换集合

    json - 如果列名称包含APOSTROPHE(),则无法在SQLSERVER中插入JSON数据

    python - www.example.com/post/21/edit 是 RESTful URI 吗?我想我知道答案,但还有一个问题

    asp.net - 我可以合并 SignalR 和 RESTful API 吗?