Jackson Circular Dependencies

I have a circular addiction I'm trying to solve with. Take these two classes - the boiler plate code is removed for demonstration purposes.

Grade 1

@Entity @Table(name = "T_CREDENTIAL") @Cache(usage = CacheConcurrencyStrategy.READ_WRITE) @JsonIdentityInfo(generator=ObjectIdGenerators.IntSequenceGenerator.class, property="@id") public class Credential implements Serializable { @Id @GeneratedValue(strategy = GenerationType.AUTO) private Long id; //Removed @JsonIgnore as want to disable certain fields if no credentials are available //Also fetch this in an eager fashion instead of lazily loading it @OneToMany(mappedBy = "credential",fetch=FetchType.EAGER) private Set<UserTask> userTasks = new HashSet<>(); .... ..... 

Class 2

 @Entity @Table(name = "T_USERTASK") @Cache(usage = CacheConcurrencyStrategy.READ_WRITE) @JsonIdentityInfo(generator=ObjectIdGenerators.IntSequenceGenerator.class, property="@id") public class UserTask implements Serializable { /** * */ private static final long serialVersionUID = -8179545669754377924L; @Id @GeneratedValue(strategy = GenerationType.AUTO) @Column(name = "id") private Long id; @ManyToOne(fetch=FetchType.EAGER) @NotNull(message = "Credential must not be null") private Credential credential; 

Unfortunately, I have cases where UserTask needs to load credentials and cases where Credential needs to load Usertasks

The @JsonIdentityInfo annotation seems to be doing its job. If I load all UserTasks, it loads the first userTask and its credentials, but then this credential object also loads all the user tasks that are assigned to this credential. He then encounters a new @Id or userTask, which now loads it with credentials instead of two user tasks.

Any ideas what I can do to get around this?

Greetings Damien

- Update question I updated my code now to use the new annotations mentioned by other users.

Grade 1

  @Entity @Table(name = "T_CREDENTIAL") @Cache(usage = CacheConcurrencyStrategy.READ_WRITE) public class Credential implements Serializable { /** * */ private static final long serialVersionUID = -8696943454186195541L; //Removed @JsonIgnore as want to disable certain fields if no credentials are available //Also fetch this in an eager fashion instead of lazily loading it @OneToMany(mappedBy = "credential",fetch=FetchType.EAGER) @JsonManagedReference("credential") private Set<UserTask> userTasks = new HashSet<>(); .... .... 

Class 2

 @Entity @Table(name = "T_USERTASK") @Cache(usage = CacheConcurrencyStrategy.READ_WRITE) public class UserTask implements Serializable { @Id @GeneratedValue(strategy = GenerationType.AUTO) @Column(name = "id") private Long id; @ManyToOne(fetch=FetchType.EAGER) @NotNull(message = "Credential must not be null") @JsonBackReference("credential") private Credential credential; .... .... 

Now these classes now work and do not have circular dependencies. However, when I make a request now to get my custom tasks or a single task, the credential object is not returned, even if I do not have the @jsonIgnore annotation specified. Any ideas what causes this?

+5
source share
2 answers

If you are using Jackson HttpMessageConverter, you should check their documentation - http://wiki.fasterxml.com/JacksonFeatureBiDirReferences

You should add the annotations shown here:

 public class NodeList { @JsonManagedReference public List<NodeForList> nodes; } public class NodeForList { public String name; @JsonBackReference public NodeList parent; public NodeForList() { this(null); } public NodeForList(String n) { name = n; } } 
+3
source

I went with the annotation below at the end

 @JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id") 

Thanks for helping the guys

0
source

Source: https://habr.com/ru/post/1215794/


All Articles