java 41 lines · 7 steps

Projection interfaces in Spring Data JPA

A repository maps a grouped revenue query straight onto a typed interface, computed fields and all.

Explained by highlit
1package com.example.orders.repository;
2 
3import com.example.orders.domain.Order;
4import org.springframework.data.jpa.repository.JpaRepository;
5import org.springframework.data.jpa.repository.Query;
6import org.springframework.data.repository.query.Param;
7 
8import java.math.BigDecimal;
9import java.time.Instant;
10import java.util.List;
11 
12public interface OrderRepository extends JpaRepository<Order, Long> {
13 
14 interface CustomerRevenue {
15 Long getCustomerId();
16 String getCustomerName();
17 long getOrderCount();
18 BigDecimal getTotalRevenue();
19 
20 default boolean isHighValue() {
21 return getTotalRevenue().compareTo(new BigDecimal("1000")) >= 0;
22 }
23 }
24 
25 @Query("""
26 select c.id as customerId,
27 c.name as customerName,
28 count(o) as orderCount,
29 coalesce(sum(o.total), 0) as totalRevenue
30 from Order o
31 join o.customer c
32 where o.placedAt >= :since
33 and o.status = com.example.orders.domain.OrderStatus.COMPLETED
34 group by c.id, c.name
35 having sum(o.total) > :threshold
36 order by sum(o.total) desc
37 """)
38 List<CustomerRevenue> findRevenueByCustomerSince(
39 @Param("since") Instant since,
40 @Param("threshold") BigDecimal threshold);
41}
01 / 01
STEP 01

Walkthrough

Space play step click any line
Three takeaways
  1. 1Interface projections let Spring Data return exactly the columns a query selects, without a dedicated entity or DTO class.
  2. 2JPQL aliases must match projection getter names so Spring can bind each selected value to the right accessor.
  3. 3Default methods on a projection interface add derived logic that lives with the data rather than in calling code.

Related explainers

Share this explainer

Here's the card — post it anywhere.

Projection interfaces in Spring Data JPA — share card
Made with highlit — turn any snippet into a walkthrough like this in about a minute.
Explain your code