Files
llm-wiki/vault/20-evidence/official-docs/spring-data-jpa-projections-spring-official.md
T

8.9 KiB

title, source_type, url, archive_url, status, confidence, tags, related_branches, related_projects, created, last_reviewed
title source_type url archive_url status confidence tags related_branches related_projects created last_reviewed
official-doc / Spring Data JPA — Projections (Spring Official Reference) official-doc https://docs.spring.io/spring-data/jpa/reference/repositories/projections.html raw high
spring-data
jpa
projection
read-model
cqrs
query
ca-skeleton
feature-application-query-bypass-contract
ca-skeleton
2026-06-04 2026-06-04

Spring Data JPA — Projections (Spring Official Reference)

Layer: raw/official-docs/ — Spring Data JPA 공식 레퍼런스의 Projections 섹션 원문 발췌. interface-based projection, class-based projection (DTO), dynamic projection 의 공식 명세. ca-tmpl CQRS-lite read path 결정의 official-vendor-doc 근거.

Parent / 활용 branch (필수)

Branch 이 자료가 정당화하는 결정
raw/branch-notes/feature-application-query-bypass-contract D1 (aggregate 우회 + dedicated read port 에서 projection DTO 반환) 의 Spring 공식 mechanism 근거 — closed projection 이 query column subset 을 최적화함

출처 / Source

왜 저장했는지 / Why archived

ca-tmpl read path bypass 의 기술적 mechanism (projection interface, DTO constructor, query rewriting) 에 대한 공식 벤더 명세. alternative 2 (CQRS-lite with same store) 가 Spring Data JPA 위에서 구체적으로 어떻게 작동하는지의 1차 근거.

핵심 인용 / Key quotes (verbatim)

[§Interface-based projections — mechanism] "The query execution engine creates proxy instances of that interface at runtime for each element returned and forwards calls to the exposed methods to the target object."

[§Closed projections — definition] "A projection interface whose accessor methods all match properties of the target aggregate is considered to be a closed projection."

[§Closed projections — optimization] "If you use a closed projection, Spring Data can optimize the query execution, because we know about all the attributes that are needed to back the projection proxy."

[§Open projections — limitation] "Spring Data cannot apply query execution optimizations in this case, because the SpEL expression could use any attribute of the aggregate root."

[§Class-based projections — DTO] "If the store optimizes the query execution by limiting the fields to be loaded, the fields to be loaded are determined from the parameter names of the constructor that is exposed."

[§JPQL query rewriting] "If an @Query-annotated query already uses constructor expressions, then Spring Data backs off and doesn't apply DTO constructor expression rewriting."

[§Dynamic projections] "Type selection occurs at invocation time" — via <T> Collection<T> findByLastname(String lastname, Class<T> type)

[§Projection limitations — joins] "Projections limit the selection to top-level properties of the target entity. Any nested properties resolving to joins select the entire nested property causing the full join to materialize."

Claims Extracted / 추출된 주장

Claim ID Claim (이 자료가 직접 말하는 것) Evidence quote Strength Applies to Does not prove
SPRING-PROJ-C1 interface-based projection 은 runtime proxy 로 구현되어 declared accessor method 에 해당하는 target object property 만 노출 [§Interface-based] "The query execution engine creates proxy instances of that interface at runtime for each element returned and forwards calls to the exposed methods to the target object." official-vendor-doc Spring Data JPA repository method 반환 타입이 interface projection 인 경우 proxy 생성 overhead 자체는 본 문서에서 정량화 안 됨
SPRING-PROJ-C2 closed projection (모든 accessor 가 aggregate property 와 매칭) 에 대해 Spring Data 는 query execution 최적화 가능 [§Closed projections] "If you use a closed projection, Spring Data can optimize the query execution, because we know about all the attributes that are needed to back the projection proxy." official-vendor-doc 모든 accessor 가 entity top-level property 와 1:1 매칭되는 interface projection "최적화" 의 구체 방식 (column subset SELECT vs full entity load) 은 본 인용에서 명시 안 됨
SPRING-PROJ-C3 open projection (@Value SpEL expression 포함) 은 Spring Data 가 query 최적화 불가 [§Open projections] "Spring Data cannot apply query execution optimizations in this case, because the SpEL expression could use any attribute of the aggregate root." official-vendor-doc @Value 기반 computed field 가 하나라도 있는 projection interface SpEL expression 이 없는 default method 는 closed projection 으로 취급 가능
SPRING-PROJ-C4 class-based projection (DTO) 은 constructor parameter 이름으로 SELECT 할 column 을 결정 [§Class-based] "If the store optimizes the query execution by limiting the fields to be loaded, the fields to be loaded are determined from the parameter names of the constructor that is exposed." official-vendor-doc JPA constructor expression (SELECT new com.example.Dto(...) FROM ...) 을 사용하는 경우 모든 JPA provider 에서 동일하게 적용된다는 보장 — Hibernate vs EclipseLink 차이 가능
SPRING-PROJ-C5 @Query 에 constructor expression 이 이미 있으면 Spring Data 는 DTO rewriting 을 skip (back off) [§JPQL rewriting] "If an @Query-annotated query already uses constructor expressions, then Spring Data backs off and doesn't apply DTO constructor expression rewriting." official-vendor-doc 명시적 @Query + constructor expression 조합 사용 시 Spring Data 가 rewriting 을 back off 할 때 어떤 동작을 하는지 (전체 entity load 하는지) 는 본 인용에서 불명확
SPRING-PROJ-C6 nested property 로의 projection 은 join 전체를 materialize 하므로 column subset 최적화 불가 [§Limitations] "Projections limit the selection to top-level properties of the target entity. Any nested properties resolving to joins select the entire nested property causing the full join to materialize." official-vendor-doc entity 간 join 이 필요한 nested property 를 projection 에 포함할 때 top-level property 만 있는 flat projection 에는 이 제한 해당 안 됨
SPRING-PROJ-C7 dynamic projection 은 Class<T> type 파라미터로 호출 시점에 projection 타입을 선택 가능 [§Dynamic] "Type selection occurs at invocation time" (via generic Class parameter) official-vendor-doc 동일 repository method 가 domain entity 도, DTO projection 도 반환해야 할 때 dynamic projection 이 ArchUnit rule 로 강제 가능한지는 본 문서 범위 밖

Usage Boundaries / 적용 경계

  • 이 자료가 직접 증명하는 것:
    • SPRING-PROJ-C1~C7: Spring Data JPA projection 의 공식 mechanism (proxy, closed/open distinction, class-based DTO, JPQL rewriting, nested join limitation, dynamic projection)
  • 이 자료가 증명하지 않는 것:
    • projection 을 hexagonal architecture 의 어느 layer 에 둬야 한다는 guidance — 아키텍처 배치는 본 문서 범위 밖
    • closed projection 이 full entity load 대비 얼마나 빠른지의 구체 benchmark — 별도 성능 테스트 필요
    • Spring Data JPA 없이 JdbcTemplate / native query 로 projection DTO 반환 시의 동작 — 별도 참조 필요
    • ArchUnit 으로 projection 사용 패턴을 어떻게 강제하는지
  • 내 프로젝트에 적용하려면 추가 확인이 필요한 것:
    • ca-tmpl 의 hexagonal module 구조에서 projection interface 를 application layer 에 두는지 adapter layer 에 두는지 결정 (D1 결정 후)
    • Hibernate 6 기준 closed projection 이 실제로 column subset SELECT 를 생성하는지 통합 테스트 검증

메모 / Notes

  • Spring Data JPA 4.x 기준 (Spring Boot 3.4+ 에서 기본 버전)
  • interface-based projection 은 JPA entity 와 adapter layer 사이의 "clean boundary" 를 application port 에 둘 수 있게 하는 mechanism — hexagonal 에서 web DTO 와 JPA entity 가 application layer 에 leak 하지 않으면서 필요 데이터만 반환 가능
  • class-based DTO (record) 는 hexagonal application port 의 반환 타입으로 직접 사용 가능 — JPA entity (infrastructure) 가 application layer 에 노출되지 않음