Search code examples
javahibernatejpapojo

Return Entity object or POJO to UI?


I have JPA Employee persistent entity wjich has 50 fields. Sometimes I need to display all 50 fields to UI or sometime much less than that.

There are two approaches I can think of

Approach 1:-

I will continue return the Employee entity to UI. There are ways(with annotation) where I can mention which specific fields under Employee needs to be returned

Example :-

If I want to ignore MiddleName from Employee class before returning json to browser, I will create EmployeeMixin with required @JsonIgnoreProperties like below

@JsonIgnoreProperties({"MiddleName"})
public abstract class EmployeeMixin extends Employee{

}




Employee employee = new Employee ();
Map<Class<?>, Class<?>> mixinMap = new HashMap<Class<?>, Class<?>>();
mixinMap.put(Employee.class, EmployeeMixin.class);
ObjectMapper mapper = new ObjectMapper(mixinMap);
return mapper.writeValueAsString(employee);

Approach 2:-

I will make new POJO containing again all 5o fields and retuen to UI.

My question is which is better design approach ? Should I return Entity object or new Pojo object(constructed from Entity) to UI ?


Solution

  • I would prefer Approach 3, projection

    • Create a DTO object for each case with a variable set of fields you need.
    • Create a corresponding JPQL or CriteriaQueryto populate appropriate DTO.

    Having an entity like

    @Entity
    @Getter
    public class Pojo3 {
       @Id
       @GeneratedValue
       private Long id;
       @Setter
       private String f1, f2,f3;
    }
    

    you can make a DTO class with subset of fields like

    @Getter @Setter
    @AllArgsConstructor // Pojo2DTO(id,f1,f2)
    public class Pojo2DTO {
       private Long id;
       private String f1,f2;
    }
    

    that can be populated in JPQL like this test shows

    @Test
    @Transactional
    public void test() {
       Pojo3 pojo3 = new Pojo3();
       pojo3.setF1("f1");
       pojo3.setF2("f2");
       pojo3.setF3("f3");      
       em.persist(pojo3);
    
       // **NOTE** the full package path to DTO object
       TypedQuery<Pojo2DTO> tq = em.createQuery(
             "SELECT NEW org.example.jpa.manyfields.Pojo2DTO(p3.id, p3.f1, p3.f2) "
          + " FROM Pojo3 p3 WHERE p3.id=:id", Pojo2DTO.class);
       tq.setParameter("id", pojo3.getId());
    
       Pojo2DTO pojo2dto = tq.getSingleResult(); 
       log.info("{}, {}, {}", pojo2dto.getId(), pojo2dto.getF1(), pojo2dto.getF2());
    
    }