I'm trying to fetch all Employees with a relational table EmployeeCourse and to see how many Courses the employee has. When I use employeeRepo.findAll() method inside my Controller I got JSON result like this:
[{"firstName":"Pera","lastName":"Peric","employeeCourses":[],"employeeId":1},{"firstName":"Marko","lastName":"Markovic","employeeCourses":[{"id":1,"employee":{"firstName":"Marko","lastName":"Markovic","employeeCourses":[{"id":1,"employee":{"firstName":"Marko","lastName":"Markovic","employeeCourses":[{"id":1,"employee":{"firstName":"Marko","lastName":"Markovic","employeeCourses":[{"id":1,"employee":{"firstName":"Marko","lastName":"Markovic","employeeCourses":[{"id":1,"employee":{"firstName":"Marko","lastName":"Markovic","employeeCourses":[{"id":1,"employee":{"firstName":"Marko","lastName":"Markovic","employeeCourses":[{"id":1,"employee":{"firstName":"Marko","lastName":"Markovic","employeeCourses":[{"id":1,"employee":{"firstName":"Marko","lastName":"Markovic","employeeCourses":[{"id":1,"employee":{"firstName":"Marko","lastName":"Markovic","employeeCourses":[{"id":1,"employee":{"firstName":"Marko","lastName":"Markovic","employeeCourses":[{"id":1,"employee":{"firstName":"Marko","lastName":"Markovic","employeeCourses":[{"id":1,"employee":{"firstName":"Marko","lastName":"Markovic","employeeCourses":[{"id":1,"employee":{"firstName":"Marko","lastName":"Markovic","employeeCourses":[{"id":1,"employee":{"firstName":"Marko","lastName":"Markovic","employeeCourses":[{"id":1,"employee":{"firstName":"Marko","lastName":"Markovic","employeeCourses":[{"id":1,"employee":{"firstName":"Marko","lastName":"Markovic","employeeCourses":[{"id":1,"employee":{"firstName":"Marko","lastName":"Markovic","employeeCourses":[{"id":1,"employee":{"firstName":"Marko","lastName":"Markovic","employeeCourses":[{"id":1,"employee":{"firstName":"Marko","lastName":"Markovic","employeeCourses":[{"id":1,"employee":{"firstName":"Marko","lastName":"Markovic","employeeCourses":[{"id":1,"employee":{"firstName":"Marko","lastName":"Markovic","employeeCourses":[{"id":1,"employee":{"firstName":"Marko","lastName":"Markovic","employeeCourses":[{"id":1,"employee":{"firstName":"Marko","lastName":"Markovic","employeeCourses":[{"id":1,"employee":{"firstName":"Marko","lastName":"Markovic","employeeCourses":[{"id":1,"employee":{"firstName":"Marko","lastName":"Markovic","employeeCourses":[{"id":1,"employee":{"firstName":"Marko","lastName":"Markovic","employeeCourses":[{"id":1,"employee":{"firstName":"Marko","lastName":"Markovic","employeeCourses":[{"id":1,"employee":{"firstName":"Marko","lastName":"Markovic","employeeCourses":[{"id":1,"employee":{"firstName":"Marko","lastName":"Markovic","employeeCourses":[{"id":1,"employee":{"firstName":"Marko","lastName":"Markovic","employeeCourses":[{"id":1,"employee":{"firstName":"Marko","lastName":"Markovic","employeeCourses":[{"id":1,"employee":{"firstName":"Marko","lastName":"Markovic","employeeCourses":[{"id":1,"employee":{"firstName":"Marko","lastName":"Markovic","employeeCourses":[{"id":1,"employee":{"firstName":"Marko","lastName":"Markovic","employeeCourses":[{"id":1,"employee":{"firstName":"Marko","lastName":"Markovic","employeeCourses":[{"id":1,"employee":{"firstName":"Marko","lastName":"Markovic","employeeCourses":[{"id":1,"employee":{"firstName":"Marko","lastName":"Markovic","employeeCourses":[{"id":1,"employee":{"firstName":"Marko","lastName":"Markovic","employeeCourses":[{"id":1,"employee":{"firstName":"Marko","lastName":"Markovic","employeeCourses":[{"id":1,"employee":{"firstName":"Marko","lastName":"Markovic","employeeCourses":[{"id":1,"employee":{"firstName":"Marko","lastName":"Markovic","employeeCourses":[{"id":1,"employee":{"firstName":"Marko","lastName":"Markovic","employeeCourses":[{"id":1,"employee":{"firstName":"Marko","lastName":"Markovic","employeeCourses":[{"id":1,"employee":{"firstName":"Marko","lastName":"Markovic","employeeCourses":[{"id":1,"employee":{"firstName":"Marko","lastName":"Markovic","employeeCourses":[{"id":1,"employee":{"firstName":"Marko","lastName":"Markovic","employeeCourses":[{"id":1,"employee":{"firstName":"Marko","lastName":"Markovic","employeeCourses":[{"id":1,"employee":{"firstName":"Marko","lastName":"Markovic","employeeCourses":[{"id":1,"employee":{"firstName":"Marko","lastName":"Markovic","employeeCourses":[{"id":1,"employee":{"firstName":"Marko","lastName":"Markovic","employeeCourses":[{"id":1,"employee":{"firstName":"Marko","lastName":"Markovic","employeeCourses":[{"id":1,"employee":{"firstName":"Marko","lastName":"Markovic","employeeCourses":[{"id":1,"employee":{"firstName":"Marko","lastName":"Markovic","employeeCourses":[{"id":1,"employee":
A lot of rows were removed for brevity and other entities employees were not loaded.
my Entities look like this:
@Entity
public class Employee{
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "employee_id")
private Integer id;
private String firstName;
private String lastName;
@OneToMany(mappedBy = "employee", cascade = CascadeType.ALL)
Set<EmployeeCourse> employeeCourses;
// getters and setters implemented
// dont have hashCode() and equals overridden
}
@Entity
public class EmployeeCourse {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
@ManyToOne
@JoinColumn(name = "employee_id")
Employee employee;
@ManyToOne
@JoinColumn(name = "course_id")
Course course;
private Date startDate;
private Date endDate;
//have getter and setters and overridden hashCode() and equals
}
public class Course {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "course_id")
private Integer id;
private String name;
private String description;
@OneToMany(mappedBy = "course")
Set<EmployeeCourse> employeeCourses;
}
Why do I have this double results, and how to fetch them?
CodePudding user response:
It is pretty hard to read your JSON data, but I guess that with double results
I assume you are talking about the huge amount of Employee
data in your JSON response. This is due to the bi-directional relationships:
Employee
<-->EmployeeCourse
:Employee
has a reference toSet<EmployeeCourse>
andEmployeeCourse
has a reference toEmployee
.EmployeeCourse
<-->Course
:EmployeeCourse
has a reference toCourse
andCourse
has a reference toSet<EmployeeCourse>
.
This means that when Jackson serializes your Employee
s it will serialize all this duplicated information.
Having said that you have now three options:
- You turn the bi-directional relationship into a uni-directional one, by, for example, removing the
employee
attribute inEmployeeCourse
. - If for whatever reason 1. is not possible, then you might use
@JsonIgnore
so that Jackson does not serialize them. - If 2. is also not possible you may consider using DTOs. Using DTOs instead of plain Entities is usually advisable when returning data via a Controller. With DTOs, you clearly define whatever you want to include in the response to the caller. You can even reorganize your model so that it fits better the needs of the clients. You decouple your inner model and the model your API consumers know, making it possible to rework your inner model and still keep the same public model.
CodePudding user response:
Just put @JsonIgnor on top of the object which you don't want to expand. Ex. in course if you don't want to expand the result of employeeCourses then just do something like this
@OneToMany(mappedBy = "course")
@JsonIgnore
Set<EmployeeCourse> employeeCourses;