Eliminate circular JSON in Java Spring Many to Many Relationship
Using the @JsonIgnoreProperties
annotation is another alternative:
@Entity
public class Student extends AbstractUser {
@ManyToMany(fetch = FetchType.LAZY, targetEntity = Group.class)
@JoinTable(name = "GROUPS_STUDENTS",
joinColumns = { @JoinColumn(name = "student_id") },
inverseJoinColumns = { @JoinColumn(name = "group_id") })
@JsonIgnoreProperties("students")
private List<Group> groups = new ArrayList<Group>();
}
@Entity
public class Group implements Item, Serializable {
@ManyToMany(mappedBy = "groups", targetEntity = Student.class)
@JsonIgnoreProperties("groups")
private List<Student> students;
}
Find comparison between @JsonManagedReference
+@JsonBackReference
, @JsonIdentityInfo
and @JsonIgnoreProperties
here: http://springquay.blogspot.com/2016/01/new-approach-to-solve-json-recursive.html
To solve jackson infinite recursion you can use @JsonManagedReference
, @JsonBackReference
.
@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.
Find more details here: http://www.baeldung.com/jackson-bidirectional-relationships-and-infinite-recursion
public class Student extends AbstractUser {
@ManyToMany(fetch = FetchType.LAZY, targetEntity = Group.class)
@JoinTable(name = "GROUPS_STUDENTS",
joinColumns = { @JoinColumn(name = "student_id") },
inverseJoinColumns = { @JoinColumn(name = "group_id") })
@JsonManagedReference
private List<Group> groups = new ArrayList<Group>();
}
public class Group implements Item, Serializable {
@ManyToMany(mappedBy = "groups", targetEntity = Student.class)
@JsonBackReference
private List<Student> students;
}
I've solved it. I've made a custom serializer. So in Group I'll serialize the students by setting a custom annotation @JsonSerialize(using = CustomStudentSerializer.class)
CustomStudentSerializer
public class CustomStudentSerializer extends StdSerializer<List<Student>> {
public CustomStudentSerializer() {
this(null);
}
public CustomStudentSerializer(Class<List<Student>> t) {
super(t);
}
@Override
public void serialize(
List<Student> students,
JsonGenerator generator,
SerializerProvider provider)
throws IOException, JsonProcessingException {
List<Student> studs = new ArrayList<>();
for (Student s : students) {
s.setGroups(null);
studs.add(s);
}
generator.writeObject(studs);
}
}
Did the same for the groups. I've just removed the students/group component when the relationship is already nested. And now it works just fine.
Took me a while to figure this out but I posted here because it may help someone else too.