Spring- Postman too many information with ManyToMany

Viewed 231

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;
    }
}
1 Answers

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

Related