JsonManagedReference vs JsonBackReference

后端 未结 5 2115
一向
一向 2020-11-27 04:42

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

相关标签:
5条回答
  • 2020-11-27 04:47

    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<>();
     }
    
    0 讨论(0)
  • 2020-11-27 04:54

    @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; 
     }
    
    0 讨论(0)
  • 2020-11-27 04:56
    • @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.

    0 讨论(0)
  • 2020-11-27 04:56

    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

    0 讨论(0)
  • 2020-11-27 04:59

    @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.

    0 讨论(0)
提交回复
热议问题