java - tutorial - json managed reference and json back reference
JsonManagedReference vs JsonBackReference (5)
¿Me gustaría saber la diferencia entre
@JsonManagedReference
y
@JsonBackReference
en Jackson?
@JsonManagedReference es la parte de referencia directa, la que se serializa normalmente. @JsonBackReference es la parte posterior de la referencia: se omitirá de la serialización.
Entonces realmente dependen de la dirección de su relación
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;
}
Como escribe Rajat Verma, su solución funciona perfectamente. Gracias hombre, me ahorraste mucho tiempo y enojo :-)
La parte importante:
Necesita definir campos comoList
, lo tenía comoSet
antes y esta solución NO FUNCIONA (aparece como bucle infinito).
Añado mi solución:
@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
y
@JsonBackReference
están diseñados para manejar este vínculo bidireccional entre campos, uno para el rol principal y el otro para el rol
@JsonBackReference
.
Para evitar el problema, la vinculación se maneja de manera que la propiedad anotada con la anotación @JsonManagedReference se maneje normalmente (serializada normalmente, sin manejo especial para la deserialización) y la propiedad anotada con la anotación @JsonBackReference no se serializa; y durante la deserialización, su valor se establece en una instancia que tiene el enlace "administrado" (hacia adelante).
yo prefiero
@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id", scope = Long.class)
donde propiedad es el nombre del campo de clave principal y el alcance es Tipo de él
- @JsonManagedReference -> Administra la parte hacia adelante de la referencia y los campos marcados por esta anotación son los que se serializan
- @JsonBackReference -> Administra la parte inversa de la referencia y los campos / colecciones marcados con esta anotación no se serializan.
Caso de uso: tiene relaciones de uno, muchos o muchos en sus entidades / tablas y no usar lo anterior provocaría errores como
Infinite Recursion and hence - > Could not write content: Infinite recursion (Error)
Los errores anteriores se producen porque Jackson (u otro similar) intenta serializar ambos extremos de la relación y termina en una recursión.
@JsonIgnore realiza funciones similares, pero las anotaciones mencionadas anteriormente son preferibles.