Deep Dive /Java Web /15-J6

15-J6. JpaRepository → Service: Entity 반환

Hibernate가 만든 엔티티는 다시 SimpleJpaRepository 반환값으로 포장되어 서비스 계층으로 돌아옵니다. 이 단계에서 서비스는 더 이상 JPA 내부 구조를 보지 않고, Entity 또는 Optional<Entity>만 받게 됩니다.


이번 단계의 역할 — ORM 내부 결과가 서비스가 쓸 반환 타입으로 복귀한다

ORM 내부 처리 결과를 서비스 계층이 사용할 수 있는 반환 타입으로 돌려주는 단계입니다. 즉 JPA 내부 구현이 다시 애플리케이션 코드 세계로 복귀하는 지점입니다.


호출 흐름 요약 — Hibernate 엔티티 → EntityManager.find() 반환 → Optional 래핑

  1. Hibernate가 엔티티를 만들거나 찾습니다.
  2. EntityManager.find(...)가 엔티티를 반환합니다.
  3. SimpleJpaRepository.findById(...)가 이를 Optional로 감쌉니다.
  4. 서비스는 저장소 구현을 의식하지 않고 결과를 받습니다.

호출 흐름 다이어그램 — Hibernate → EntityManager → SimpleJpaRepository → Optional 반환

sequenceDiagram participant Hibernate participant EM as EntityManager participant Repo as SimpleJpaRepository participant Service Hibernate-->>EM: Entity EM-->>Repo: Entity Repo-->>Service: Optional </div> --- ## 핵심 코드 — findById()가 반환값을 Optional로 감싸 서비스에 넘긴다 ```java // SimpleJpaRepository.java public Optional findById(ID id) { Class domainType = getDomainClass(); return Optional.ofNullable(entityManager.find(domainType, id)); } ``` --- ## 코드 해설 — 서비스는 반환값만 받지만 뒤에서는 SQL 실행과 매핑이 이미 끝나 있다 서비스 입장에서는 단순히 저장소 메서드의 반환값을 받았을 뿐이지만, 그 뒤에는 Hibernate의 SQL 실행과 엔티티 매핑이 이미 끝난 상태입니다. --- ## 설계 의도 — 서비스가 EntityManager와 JDBC 세부사항을 모르게 막는 반환 경계다 서비스 계층이 `EntityManager`, `SessionImpl`, JDBC 세부사항을 몰라도 되게 하려는 반환 경계입니다. 즉 Repository는 데이터 접근 복잡도를 숨기고, 서비스에는 도메인 객체만 노출합니다. --- ## 다음 단계 연결 — MyBatis 경로인 15-M1로 이어진다 다음 문서는 MyBatis 경로인 [15-M1](/deep-dive/java-web/15-M1/)이며, 이후에는 같은 서비스 호출이 SQL 매퍼 방식으로 어떻게 흘러가는지 볼 수 있습니다.

← 이전: 15-J5. EntityManager → JpaRepository | 다음: 15-M1. Service → Mapper