'Spring- Postman too many information with ManyToMany

I have a problem with my Spring application- am practicing ManyToMany Relationship. I made two Entity- student, and groups for them- everything is good but when am trying to display them in postman i have spaghetti result like :

{"id":4,"lastName":"guzik","groups":[{"id":1,"groupName":"grupka","students": ....(shorter version, its about 1000 lines) [{"id":1,"lastName":"smith","groups":[{}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}]}{"timestamp":"2022-04-25T08:25:31.387+00:00","status":200,"error":"OK","path":"/api/student/4"}

What am doing wrong ?

enter code here

@RestController
@RequestMapping("/api")
public class MainController{
    @Autowired
    GroupRepo groupRepo;
    @Autowired
    StudentRepo studentRepo;

    @GetMapping("/student/{id}")
    ResponseEntity<?> getStudent(@PathVariable long id){
        Optional<Students> student=studentRepo.findById(id);
        return ResponseEntity.ok().body(student);
    }
    @GetMapping("/group/{id}")
    ResponseEntity<?> getGroup(@PathVariable long id){
        Optional<Groupssss> group=groupRepo.findById(id);
        return ResponseEntity.ok().body(group);
    }
    @GetMapping("/student/{id}/groups")
    ResponseEntity<?> studentGroups(@PathVariable long id){
        Students student=studentRepo.findById(id).orElseThrow(()-> new UsernameNotFoundException("student not found"));
        return ResponseEntity.ok().body(student.getGroups());
    }
    @PostMapping("/add")
    @Transactional
    ResponseEntity<?> addStudentToGroup(@RequestHeader long id) throws Exception{
        Students student=studentRepo.findById(id)
                .orElseThrow(()-> new UsernameNotFoundException("student not found"));

        Groupssss group=groupRepo.findByGroupName("grupka").orElseThrow(Exception::new);

        student.addGroup(group);
        studentRepo.save(student);

        return ResponseEntity.ok().build();
    }

@Entity
public class Groupssss {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private long id;

    private String groupName;

    @ManyToMany(fetch = FetchType.LAZY,
            cascade = {
                    CascadeType.PERSIST,
                    CascadeType.MERGE
            },
            mappedBy = "groups")
    private Set<Students> students=new HashSet<>();

    public void setGroupName(String groupName) {
        this.groupName = groupName;
    }

    public void setStudents(Set<Students> students) {
        this.students = students;
    }

    public Set<Students> getStudents() {
        return students;
    }

    public String getGroupName() {
        return groupName;
    }
    public long getId() {
        return id;
    }
    public void setId(long id) {
        this.id = id;
    }


}

@Entity
@Table(name="students")
public class Students {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    long id;

    String firstName;
    String lastName;

    @ManyToMany(fetch = FetchType.LAZY,
            cascade = {
                    CascadeType.PERSIST,
                    CascadeType.MERGE
            })
    @JoinTable(name="student_group",
            joinColumns = @JoinColumn(name="student_id"),
            inverseJoinColumns = @JoinColumn(name="group_id"))
    Set<Groupssss> groups=new HashSet<>();

    public Students(){}

    public Students(String firstName, String lastName){
        this.firstName=firstName;
        this.lastName=lastName;
    }

    public void addGroup(Groupssss group){
        this.groups.add(group);
        group.getStudents().add(this);
    }

    public Set<Groupssss> getGroups() {
        return groups;
    }

    public String getLastName() {
        return lastName;
    }

    public String getName() {
        return firstName;
    }

    public void setGroups(Set<Groupssss> groups) {
        this.groups = groups;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

    public void setName(String firstName) {
        this.firstName = firstName;
    }
    public long getId() {
        return id;
    }
    public void setId(long id) {
        this.id = id;
    }
}


Solution 1:[1]

If you use ManyToMany relationship, It calls the Parent and the Child entity recursively when you try to get List of it. There must be ignorance in child entity like:

In Parent entity you could call @JsonManagedReference

In Child entity you could call @JsonBackReference

Documentation is here: Bidirectional Relationships

public class User {
    public int id;
    public String name;

    @JsonManagedReference
    public List<Item> userItems;
}

public class Item {
    public int id;
    public String itemName;

    @JsonBackReference
    public User owner;
}

Or you can use @JsonIgnore on top of the Parent declaration in Child entity. Some of the case it gets worst when you use JsonIgnore.

Documentation is here: Jackson Ignore Properties

public class MyDto {

    private String stringValue;
    @JsonIgnore
    private int intValue;
    private boolean booleanValue;

    public MyDto() {
        super();
    }
}

Or use @JsonIgnoreProperties when you need to ignore many fields

@JsonIgnoreProperties(value = { "intValue" })
public class MyDto {

    private String stringValue;
    private int intValue;
    private boolean booleanValue;

    public MyDto() {
        super();
    }
}

!Enjoy

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 frxdude