Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JsonManagedReference vs JsonBackReference

Tags:

java

jackson

I would like to know the difference between @JsonManagedReference and @JsonBackReference in Jackson?

like image 686
ooozguuur Avatar asked Jul 09 '15 13:07

ooozguuur


People also ask

What is the use of JsonManagedReference and JsonBackReference annotations?

The @JsonManagedReference annotation is a forward reference that includes during the serialization process whereas @JsonBackReference annotation is a backreference that omits during the serialization process.

What is JsonIdentityInfo?

The @JsonIdentityInfo annotation is used when an object has a parent-child relationship in the Jackson library. The @JsonIdentityInfo annotation is used to indicate the object identity during the serialization and deserialization process.

What is @JsonIgnoreProperties?

@JsonIgnoreProperties is used at class level to mark a property or list of properties to be ignored.

What is @JsonIgnore in spring boot?

The. @JsonIgnore. annotation marks a field in a POJO to be ignored by Jackson during serialization and deserialization. Jackson ignores the field in both JSON serialization and deserialization.


5 Answers

@JsonManagedReference is the forward part of reference – the one that gets serialized normally. @JsonBackReference is the back part of reference – it will be omitted from serialization.

So they really depend on the direction of your relationship

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; 
 }
like image 155
david99world Avatar answered Oct 03 '22 14:10

david99world


I prefer
@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id", scope = Long.class)
where property is the name of primary key field and scope is Type of it

like image 30
Rajat Avatar answered Oct 03 '22 16:10

Rajat


  • @JsonManagedReference -> Manages the forward part of the reference and the fields marked by this annotation are the ones that get Serialised
  • @JsonBackReference -> Manages the reverse part of the reference and the fields/collections marked with this annotation are not serialised.

Use case: You have a one-many or many-many relationships in your entities/tables and not using the above would lead to errors like

Infinite Recursion and hence stackoverflow - > Could not write content: Infinite recursion (StackOverflowError)

The above errors occurs because Jackson (or someother similiar) tries to serialise both ends of the relationship and ends up in a recursion.

@JsonIgnore performs similiar functions but the above mentioned annotations are preferable.

like image 30
HopeKing Avatar answered Oct 03 '22 16:10

HopeKing


As write Rajat Verma, his solution works perfectly. Thanks man you saved me lot of time and anger :-)

The important Part:
You need define fields as List, I had that as Set before and this solution NOT WORKING (appears as infinite loop)!

I add my solution:

@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<>();
 }
like image 39
Andrew Sneck Avatar answered Oct 03 '22 16:10

Andrew Sneck


@JsonManagedReference and @JsonBackReference are designed to handle this two-way linkage between fields, one for Parent role, the other for Child role.

For avoiding the problem, linkage is handled such that the property annotated with @JsonManagedReference annotation is handled normally (serialized normally, no special handling for deserialization) and the property annotated with @JsonBackReference annotation is not serialized; and during deserialization, its value is set to instance that has the "managed" (forward) link.

like image 37
ooozguuur Avatar answered Oct 03 '22 14:10

ooozguuur