5

I am having a few tables in my DB. Employee, Address, Phone_id

Table Employee
====================
ID | Emp_Name | Address_id | Phones_id

Table Address
====================
ID | Block_no | City | State

Table Phone_id
====================
ID | Phone_1 | Phone_2 | Phone_3

When I display the JSON received directly from repository, it works, but not in the format expected by UI. I wish to make some changes to the received JSON. Basically, transform it and then provide response over REST.

So my questions are:

  1. Is there any Spring way to solve my requirement. So that I can just map my entity class to some JSON class.

  2. Is there any design pattern that can be used in such a scenario.

Thanks a bunch!

Jens Schauder
  • 77,657
  • 34
  • 181
  • 348
Abhay Dandekar
  • 1,230
  • 10
  • 30
  • Have you tried using `@JsonProperty` from Jackson on the fields of your entity classes? – B Thuy Feb 15 '18 at 13:29
  • 2
    Can you please elaborate more on what kind of changes you are trying to make to the JSON? A sample would help us answer your query. – Rahul Kargwal Feb 15 '18 at 13:33
  • Can you plz post the source code for your classes Employee,Phone,Address so that we can see your Jackson annotations ? – e2rabi Feb 15 '18 at 14:17
  • Yaa, I did try @JsonProperty. The problem is I can only change the names of JSON. While I wish to change the structure. – Abhay Dandekar Feb 15 '18 at 14:25
  • @AbhayDandekar What do you mean by structure? Post the current state and what do you expect to be changed? – Ram Feb 16 '18 at 07:08

1 Answers1

6

It is advisable to keep you @Entity classes and your JSON representation classes separated.

Let's say you have @Entity class Employee. One option is to use the same Employee class to describe your database entity (using let's say JPA annotations) and then use the same Employee class to describe the JSON you want to return to the client (using let's say Jackson annotations).

That's considered bad practice for various reasons. Most common one is that most of the time you don't want all your entities to be mapped 1:1 to your JSON response.

In order to deal with this, a common approach is to create a separate Employee class to describe your JSON representation. You can call it EmployeeDto.

Then you have to write a custom logic that maps @Entity Employee to EmployeeDto.

You can use static factory method like so:

//Persistence layer class
@Entity
public class Employee {
  @Id
  @GeneratedValue
  @Column(name = "id")
  private Long id;

  @Column(name = "first_name")
  private String firstName;

  @Column(name = "last_name")
  private String lastName;

  //getters/setters
}

//REST layer class
public class EmployeeDto {
  @JsonProperty("first_name")
  private String firstName;
  @JsonProperty("last_name")
  private String lastName;

  public EmployeeDto() {}

  // you can do any transforamtion/validation here
  public static EmployeeDto fromEntity(Employee employee){
    EmployeeDto dto = new EmployeeDto();
    dto.setFirstName(employee.getFirstName);
    dto.setLastName(employee.getLastName);
  }

  //getters/setters
}

Then your controller will return List<EmployeeDto> instead of @Entity Employee.

UPDATE:

Spring doesn't provide automatic conversion mechanism between DTO and Entity object. I think it depends on the complexity of the classes and number of pairs (DTO/Entity), but most of the time it's easy enough to implement the conversion yourself.

Of course there are libraries out there, which provide some level of automation with the mapping:

hovanessyan
  • 30,580
  • 6
  • 55
  • 83
  • Thanks for your answer. I was looking forward to some Spring entity which can tie my DTO class and my entity class. Is that possible? With some annotation or something. Otherwise, we always have to code it with our own logic. – Abhay Dandekar Feb 16 '18 at 12:57
  • There is one really bad idea here in this answer and that is adapter code is the most buggy code there is. I have seen way too many times people put the first_name field into the lastName Property and the lastNameProperty into the middle_initial field. I am not saying DTOs are bad, I am saying this adapter code is a really bad practice. If you are going to use DTOs, which you should in many Use Cases, then use some ModelMapping tool like in this post I found https://www.baeldung.com/entity-to-and-from-dto-for-a-java-spring-application – bytor99999 Aug 31 '18 at 18:13
  • Bugginess is property of the coder, not the code itself. If somebody is not focused enough to do a proper field mapping by hand well... By the way the answer already contains reference to two mapping frameworks that do the job "automatically", but it's for the people who care to read it. There's a difference if the mapping logic is inside the classes (introduces coupling) or outside (e.g. mapper classes you write yourself or use a framework), but either way it's better not to use Entities as DTO classes in higher layers in the traditional layered architecture model. – hovanessyan Sep 07 '18 at 17:46