JsonManagedReference против JsonBackReference

Я хотел бы знать разницу между @JsonManagedReference а также @JsonBackReference в Джексоне?

4 ответа

Решение

@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; 
 }
  • @JsonManagedReference -> Управляет передней частью ссылки, и поля, отмеченные этой аннотацией, становятся сериализованными.
  • @JsonBackReference -> Управляет обратной частью ссылки, а поля / коллекции, отмеченные этой аннотацией, не сериализуются.

Вариант использования: у вас есть отношения один-много или много-много в ваших сущностях / таблицах, и если вы не используете вышеперечисленное, это приведет к таким ошибкам, как

Infinite Recursion and hence stackru - > Could not write content: Infinite recursion (StackruError)

Вышеуказанные ошибки происходят из-за того, что Джексон (или что-то подобное) пытается сериализовать оба конца отношений и заканчивается рекурсией.

@JsonIgnore выполняет аналогичные функции, но вышеупомянутые аннотации предпочтительнее.

я предпочитаю
@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id", scope = Long.class)
где свойство - это имя поля первичного ключа, а область действия - его тип.

Как пишет Раджат Верма, его решение работает отлично. Спасибо человек, ты сэкономил мне много времени и гнева:-)

Важная часть:
Вам нужно определить поля как 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<>();
 }

@JsonManagedReference а также @JsonBackReference предназначены для обработки этой двусторонней связи между полями, одно для родительской роли, другое для дочерней роли.

Чтобы избежать этой проблемы, связывание обрабатывается так, что свойство, аннотированное аннотацией @JsonManagedReference, обрабатывается нормально (обычно сериализуется, без специальной обработки для десериализации), а свойство, аннотированное аннотацией @JsonBackReference, не сериализуется; и во время десериализации его значение устанавливается равным экземпляру, который имеет "управляемую" (прямую) ссылку.

Другие вопросы по тегам