Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Correct usage of Entity AND DTO to provide Json in Restful web service

There are many articles stating that using DTOs is not necessary with JPA/hibernate

Use the open session in view pattern, or a disciplined assembly phase to avoid problems with unfetched data.Hibernate frees the developer from writing tedious Data Transfer Objects (DTO)... The above lines are from https://docs.jboss.org/hibernate/orm/3.5/reference/en/html/best-practices.html

Also In an article by a SO member Bohzo I read DTO's are rarely required

Even in articles against exposing entities state that there is no need of having a DTO when Entities do not have any behavior (when they are POJOs) as in the anemic domain model

Let's Say there is an Entity class

class Department{
    List<Employee> employees //lazily loaded collection 

Each object in the collection contains another lazily loaded collection

 class Employee{
    List<Account> accounts

There is a getDepartment() method which is used by a restful service to provide Json information of the Department.

The possible solutions are

Solution 1) As per hibernate documentation opening and closing the hibernate session per request (that is the uppermost method in controller is transactional?) or better using Spring's OpenSessionInViewFilter as per this SO post

Why can't hibernate re-open a session and fetch the lazily loaded object instead of throwing an exception?Is there a way to configure this with JPA/hibernate?

Solution 2) Again as in hibernate doc another way is to have an assembly phase.What exactly does it mean ? Break down the getDepartment API into different API's of the DAO ?

Solution 3)Use DTO's Even with DTO's how can the persistence layer know whether view needs a fully loaded Department or not.This leads to breaking the API into getDepartmentOnly() getDepartmentWithEmployees() and others saying whether to get 100% of the department object or a part of it One API broke down into many and one entity mapped to many DTO's

Solution 4) As in bohzo's article with paginated views avoid lazy loading and have queries to fetch limited results

Please correct Solution 2 and explain what is intended in the hibernate documentation?

like image 433
bl3e Avatar asked Oct 19 '22 06:10

bl3e


1 Answers

Assembly phase in the Hibernate documentation means:

public Department getDepartmentWithEmployees(Long departmentId) {
   Department result = em.find(Department.class, departmentId);
   Hibernate.initialize(result.getEmployees());
   return result;
}

Or:

public Department getDepartmentWithEmployees(Long departmentId) {
   String query = "select d from Department d join fetch d.employees where d.id = :departmentId";
   ...
}

Or ...

Basically, it's up to you to fetch the necessary data to provide the balance between code readability and maintainability vs performance (the number of different APIs vs the amount of data fetched).

This is not a JPA/Hibernate specific issue; you would need to consider this with any other persistence framework (or with direct JDBC) as well.

like image 135
Dragan Bozanovic Avatar answered Oct 22 '22 00:10

Dragan Bozanovic