JsonManagedReference与JsonBackReference

ozg*_*gur 31 java jackson

我想知道杰克逊@JsonManagedReference和@JsonBackReference杰克逊之间的区别吗?

dav*_*rld 51

@JsonManagedReference是引用的前向部分 - 正常序列化的部分.@JsonBackReference是引用的后半部分 - 它将从序列化中省略.

所以他们真的依赖于你们关系的方向

public class User {
    public int id;
    public String name;

    @JsonBackReference
    public List<Item> userItems; 
} 

public class Item {
    public int id;
    public String itemName;

    @JsonManagedReference
    public User owner; 
 }
Run Code Online (Sandbox Code Playgroud)

  • http://www.baeldung.com/jackson-bidirection-relationships-and-infinite-recursion (11认同)

And*_*eck 7

Rajat Verma 写道,他的解决方案非常有效。谢谢你,你节省了我很多时间和愤怒:-)

重要的部分:
您需要将字段定义为List,我和以前一样Set,这个解决方案不起作用(显示为无限循环)!

我添加我的解决方案:

@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id", scope = Long.class)
public class Agent {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    @ManyToMany(mappedBy = "subscribers")
    @ApiModelProperty(dataType = "List", example = "[1,2,3]") // for Swagger
    @JsonIdentityReference(alwaysAsId = true) // show only id of Topic
    private final List<Topic> subscribeTopics = new ArrayList<>()
}

 @JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id", scope = Long.class)
 public class Topic {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    @ManyToMany(cascade = {CascadeType.DETACH, CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REFRESH})
    @JoinTable(name = "topic_agent",
        joinColumns = @JoinColumn(name = "fk_topic_id"),
        inverseJoinColumns = @JoinColumn(name = "fk_agent_id"))
    @ApiModelProperty(dataType = "List", example = "[1,2,3]")
    @JsonIdentityReference(alwaysAsId = true)
    private final List<Agent> subscribers = new ArrayList<>();
 }
Run Code Online (Sandbox Code Playgroud)


Hop*_*ing 6

  • @JsonManagedReference -> 管理引用的前向部分,这个注解标记的字段是被序列化的
  • @JsonBackReference -> 管理引用的反向部分,并且使用此注释标记的字段/集合不会被序列化。

用例: 您的实体/表中有一对多或多对多的关系,不使用上述方法会导致错误,例如

Infinite Recursion and hence stackoverflow - > Could not write content: Infinite recursion (StackOverflowError)
Run Code Online (Sandbox Code Playgroud)

发生上述错误是因为 Jackson(或其他类似的人)试图序列化关系的两端并以递归结束。

@JsonIgnore 执行类似的功能,但上述注释更可取。


ozg*_*gur 5

@JsonManagedReference并且@JsonBackReference旨在处理字段之间的这种双向链接,一个用于父角色,另一个用于子角色。

为避免该问题,对链接进行处理,使得使用@JsonManagedReference 注解的属性正常处理(正常序列化,反序列化没有特殊处理),而不序列化@JsonBackReference 注解的属性;并且在反序列化期间,它的值被设置为具有“托管”(前向)链接的实例。

  • 如果@JsonBackReference 注释没有被序列化,那么它是如何在没有首先被序列化的情况下“反序列化”的? (2认同)

Raj*_*jat 5

我更喜欢
@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id", scope = Long.class)
属性是主键字段的名称,范围是它的类型