如何使用自引用处理实体的RESTful响应 [英] How to handle RESTful response of Entity with self-reference

查看:119
本文介绍了如何使用自引用处理实体的RESTful响应的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a class Foo which have reference to itself. This is rough example of situation I have been in.

@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检索到的所有必需数据。

When i pass Foo object to JSON response generator, all required getters are initiated and all required data retrieved from DB by JPA.

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

Now the problem is that if i remove @JsonIgnore from self-reference field I'm getting parent info, and parent parent info and etc.

我想要的是我可以限制检索到的父信息的深度。
例如。:

What I want is that I could limit deep of retrieved parent info. For example.:


  • 深0 - 我只会得到Foo数据

  • Deep 1 - 我将获得Foo和Foo父母的数据

  • Deep 2 - 我将获得Foo和Foo父母和Foo父母的资料
    等。

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

Maybe there is a simple solution with annotations or smth, because i couldn't find anything.

编辑:

解决了自定义序列化程序和一些递归魔法的问题。

Solved this problem with custom serializer and some recursion magic.

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 属性以及它的,所以你不会得到一个递归关系并避免延迟加载异常。

I think the best approach would be to create a custom DTO object to gather all your Foo properties as well as its parent, so you won't get a recursion relationship and avoid lazy loading exceptions.

所以你将保持你的实体不变:

So you will keep your entity as it is:

@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对象:

And create a custom DTO object like this:

public class FooDto() {

   private Long id;
   private Foo parent;

   //getters and setters here
}

然后你可以使用此DTO将JSOn结果存储在您的请求中。

Then you can use this DTO to store JSOn results in your requests.

您可以查看 使用DTO(数据传输对象)的重点是什么? 了解更多详情。

You can take a look at What is the point of using DTO (Data Transfer Objects)? for further details.

@JsonIgnore 文档:

@JsonIgnore documentation:

根据杰克逊 @JsonIgnore 文档 没有这样的选项(属性)来指定注释的深度/级别,因为只有一个可能property value 定义此anotation是否有效。

According to the Jackson @JsonIgnore documentation there's no such option(property) to specify a depth/level for the annotation, as there's only one possible property value to define if this anotation is active or not.

这篇关于如何使用自引用处理实体的RESTful响应的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆