15-J5. EntityManager → JpaRepository: Entity 매핑
Hibernate는 JDBC 결과를 그대로 내보내지 않고, RowReader와 결과 소비기(resultsConsumer)를 통해 엔티티 그래프로 매핑합니다.
이 단계가 있어야 JPA 사용자는 ResultSet이 아니라 Entity를 받게 됩니다.
이번 단계의 역할 — 행 데이터가 애플리케이션이 쓸 객체 구조로 바뀌는 단계
JDBC 결과를 JPA 엔티티 객체로 바꾸는 단계입니다. 즉 DB의 행(row) 데이터가 애플리케이션이 사용할 수 있는 객체 구조로 변환됩니다.
호출 흐름 요약 — JdbcValues 준비 → RowReader 생성 → resultsConsumer.consume()
- Hibernate가
JdbcValues를 준비합니다. RowReader를 생성합니다.resultsConsumer.consume(...)가 결과를 순회합니다.- 처리 결과가 엔티티 객체 또는 엔티티 컬렉션으로 만들어집니다.
호출 흐름 다이어그램 — ResultSet이 RowReader와 resultsConsumer를 거쳐 Entity가 된다
sequenceDiagram
participant RS as ResultSet
participant Exec as JdbcSelectExecutorStandardImpl
participant Reader as RowReader
participant Consumer as resultsConsumer
participant Repo as JpaRepository
RS-->>Exec: jdbcValues
Exec->>Reader: createRowReader(...)
Exec->>Consumer: consume(jdbcValues, rowReader)
Consumer-->>Repo: Entity / entity list
핵심 코드 — ResultsHelper.createRowReader()가 만든 RowReader를 consume()에 넘긴다
// JdbcSelectExecutorStandardImpl.java
final var rowReader = ResultsHelper.createRowReader(
factory, rowTransformer, domainResultType, jdbcValues);
final T result = resultsConsumer.consume(
jdbcValues,
session,
processingOptions,
valuesProcessingState,
rowProcessingState,
rowReader
);
코드 해설 — 중간 처리 계층 덕분에 단건·컬렉션·조인·캐시를 공통 방식으로 다룬다
Hibernate는 ResultSet을 직접 엔티티로 바꾸지 않고, 중간에 JdbcValues, RowReader, resultsConsumer 같은 처리 계층을 둡니다.
이 구조 덕분에 단건 조회, 컬렉션 조회, 조인 결과, 캐시 연동 같은 다양한 케이스를 공통 방식으로 다룰 수 있습니다.
설계 의도 — 행 데이터를 객체 그래프로 바꾸는 일을 독립 계층에 둔다
SQL 실행과 결과 매핑을 분리해 ORM의 핵심 책임인 “행 데이터 → 객체 그래프 변환”을 독립적으로 처리하기 위한 구조입니다. 이 단계가 JPA와 단순 JDBC 템플릿의 큰 차이 중 하나입니다.
다음 단계 연결 — 15-J6 매핑된 엔티티가 서비스로 돌아가는 과정으로 이어진다
다음 문서 15-J6에서는 매핑된 엔티티가 SimpleJpaRepository를 거쳐 서비스로 어떻게 돌아가는지 정리합니다.
← 이전: 15-J4. DB → EntityManager | 다음: 15-J6. JpaRepository → Service