Recently, I started a new job (4 months now) and I still have a lot to learn from Spring. One of the issues we're having is that when we bring objects from the DB and map them into (Repository -> Service -> Controller) a JSON, it brings a lot of unnecessary data - For example (small example):
We have an Employee class which has a Department object and it brings the following:
{
'EmployeeId':1,
'Name':'John',
'Email':'[email protected]'
'Department': {
'DepartmentId':1,
'name':'Development',
'location':'Somewhere',
}
}
Class details:
@Entity
@Table(name = "Employees")
@NamedQuery(name = "Employee.findAll", query = "SELECT e FROM Employees e")
public class Employee implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "EmployeeId")
private long EmployeeId;
@Column(name = "Email")
private String email;
@Column(name = "address")
private String address;
@ManyToOne
@JoinColumn(name = "DepartmentId")
@JsonBackReference(value = "department_employee")
private Departament departament;
// Other attributes, setters & getters
}
If I want to build a "custom" mapper, which is the best practice? Or how can I implement something that allows me to create a JSON that brings me something like this:
{
'EmployeeId':'1',
'Name':'John',
'Email':'[email protected]'
}
I've been doing some research and I stumbled across the following examples:
Jackson's @JsonView, @JsonFilter and Spring
Also I've been thinking about using a generic object that contains a HashMap so I can include, on the Controller, the data that I want or need for an specific screen.
I really appreciate any help - hope the question is clear enough.
One library that works particularly well for me is Model Mapper. The way I use it is by having your Domain object (like you do now) and a DTO. So in your case, Employee and EmployeeDTO. This allows for clear separation between the layers of your app, and mapping between employee and employeeDto with model mapper is quite easy, just modelMapper(employee, EmployeeDTO.class)
for instance. All you gotta do for the simple cases is name the properties with the same name in the domain class and the dto class, and the library will take care of copying the values. For more complicated cases it has several alternatives that will still make your code clean.