Spring Data JPA DTO Projection Example

🎓 Top 15 Udemy Courses (80-90% Discount): My Udemy Courses - Ramesh Fadatare — All my Udemy courses are real-time and project oriented courses.

▶️ Subscribe to My YouTube Channel (178K+ subscribers): Java Guides on YouTube

▶️ For AI, ChatGPT, Web, Tech, and Generative AI, subscribe to another channel: Ramesh Fadatare on YouTube

Using DTO (Data Transfer Object) projections in Spring Data JPA is a powerful way to select specific columns from a database, reducing the overhead of selecting unnecessary data. Here's a step-by-step guide on how to set up DTO projections using an Employee entity as an example.

1. Setting up the project

Ensure you have the necessary dependencies in your pom.xml:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>

2. Define the Entity

@Entity
public class Employee {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String firstName;
    private String lastName;
    private String department;
    private Double salary;

    // getters, setters, etc.
}

3. Create a DTO Projection

Suppose you want to retrieve only the firstName, lastName, and department:
public class EmployeeInfoDto {
    private final String firstName;
    private final String lastName;
    private final String department;

    public EmployeeInfoDto(String firstName, String lastName, String department) {
        this.firstName = firstName;
        this.lastName = lastName;
        this.department = department;
    }

    // getters
}
Make sure the fields are final and initialized via a constructor. 

4. Create the Repository

Define a custom query using JPQL in the repository:
public interface EmployeeRepository extends JpaRepository<Employee, Long> {

    @Query("SELECT new com.yourpackage.EmployeeInfoDto(e.firstName, e.lastName, e.department) FROM Employee e")
    List<EmployeeInfoDto> findAllEmployeeInfo();
}
The @Query selects the desired fields and maps them to the EmployeeInfoDto

5. Use the Repository in a Service

Now, utilize the repository method in your service layer:
@Service
public class EmployeeService {

    @Autowired
    private EmployeeRepository employeeRepository;

    public List<EmployeeInfoDto> getAllEmployeeInfo() {
        return employeeRepository.findAllEmployeeInfo();
    }
}

6. Test the Service

Set up a test to ensure your DTO projections work correctly:
@RunWith(SpringRunner.class)
@SpringBootTest
public class EmployeeServiceTest {

    @Autowired
    private EmployeeService employeeService;

    @Test
    public void testFetchEmployeeInfo() {
        List<EmployeeInfoDto> employeeInfo = employeeService.getAllEmployeeInfo();
        for (EmployeeInfoDto info : employeeInfo) {
            assertNotNull(info.getFirstName());
            assertNotNull(info.getLastName());
            assertNotNull(info.getDepartment());
        }
    }
}

7. Why Use DTO Projections? 

Performance: By selecting only the needed columns from a database, there's less data to transfer, process, and map. 

Avoiding Fetching Sensitive Data: If an entity has sensitive attributes (like passwords or private keys), using DTOs can avoid accidentally fetching or exposing them. 

Flexibility: DTOs allow for shaping data differently based on the context. The same entity can have multiple DTOs based on different use cases.

My Top and Bestseller Udemy Courses. The sale is going on with a 70 - 80% discount. The discount coupon has been added to each course below:

Comments

Spring Boot 3 Paid Course Published for Free
on my Java Guides YouTube Channel

Subscribe to my YouTube Channel (165K+ subscribers):
Java Guides Channel

Top 10 My Udemy Courses with Huge Discount:
Udemy Courses - Ramesh Fadatare