- 순수 JPA를 공부하면서 프로젝트 할 때 사용을 많이 했던 Spring Data JPA에서 순수 JPA가 어디서 돌아가는지 궁금하게 되었다.
import java.util.List;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
@Repository
public interface FoldersRepository extends JpaRepository<Folders, Long>{
List<Folders> findAllByUserId(Long userId);
}
위 코드는 스프링 data jpa를 사용한 코드이다. 인터페이스인 JPARepository를 따라가면 다음과 같은 형태가 나오게 된다.

각 인터페이스들이 무엇을 하는지는 아직 파악을 못했지만 순수 JPA 코드는 SimpleJpaRepository에서 진행된다.
- 순수 JPA에서 createEntityManagerFactory, createEntityManger, close, 트랜잭션.begin(), 트랜잭션.commit() 같은 걸 진행하게 된다.
SimpleJpaRepository에서 위를 다 하는 지 조금 더 파헤쳐보자
밑은 SimpleJpaRepository 코드이다.(부분만 가져왔다.)
@Repository
@Transactional(readOnly = true)
public class SimpleJpaRepository<T, ID> implements JpaRepositoryImplementation<T, ID> {
private static final String ID_MUST_NOT_BE_NULL = "The given id must not be null";
private static final String IDS_MUST_NOT_BE_NULL = "Ids must not be null";
private static final String ENTITY_MUST_NOT_BE_NULL = "Entity must not be null";
private static final String ENTITIES_MUST_NOT_BE_NULL = "Entities must not be null";
private static final String EXAMPLE_MUST_NOT_BE_NULL = "Example must not be null";
private static final String SPECIFICATION_MUST_NOT_BE_NULL = "Specification must not be null";
private static final String QUERY_FUNCTION_MUST_NOT_BE_NULL = "Query function must not be null";
...
SimpleJpaRepository가 하는 일 분석
EntityManagerFactory 불러오기 (createEntityManagerFactory)
- Springboot가 애플리케이션 시작할 때 이걸 함.
- JPA를 순수하게 쓰면 persistence.createEntityMangerFactory(..)를 호출하지만, Spring boot에선LocalContainerEntityManagerFactoryBean 같은 설정을 통해 EMF를 Bean으로 만든다.
→ SimpleJpaRepository가 EMF를 만들지 않는다.
EntityManager 사용(createEntityManger, close)
- Spring(정확히는 Spring ORM/ JPA 인프라)가 한다.
- 일반적으로는 트랜잭션 경계에 맞춰 “현재 스레드에 바인딩된 “EntityManager”를 제공
- 주입받는 EntityManger도 사실 프록시고, 실제 EM은 스프링이 열고 닫는다.
→ SimpleJpaRepository는 EntityManager를 new/create 하지 않고, 주입받아 사용만 한다.
트랜잭션 begin/commit/rollback 하기 전 준비
- 이건 @Transactional + PlatformTransactionManager(JpaTransactionManager) 가 한다.
- 트랜잭션 시작할 때:
- EM을 준비(필요하면 생성)
- EntityTransaction.begin()(또는 구현체 세션 시작)을 내부적으로 수행
- 정상 종료하면 commit
- 예외면 rollback
→ SimpleJpaRepository가 begin/commit/rollback을 직접 호출하지 않는다.
그러면 SimpleJpaRepository는 정확히 무엇을 하냐?
SimpleJpaRepository는 “레포지토리 메서드 구현체”로서 다음과 같은 것만 한다.
- em.persist(entity)
- em.merge(entity)
- em.find(...)
- em.remove(...)
- em.flush()
- em.createQuery(...) / Criteria 사용
즉, 비즈니스/트랜잭션 제어가 아니라 영속성 작업(persistence operations)을 호출하는 역할
이렇게 순수 JPA를 나눈이뉴는 Spring Data JPA는 Repository 구현체이고 트랜잭션/자원 관리는 “인프라 관심사”라서 분리해둔 것임.
그래서 코드가 깔끔해짐
@Transactional
public void serviceLogic() {
repository.save(entity); // repository는 persist만 호출
} // 트랜잭션 종료 지점에서 스프링이 commit/rollback + close 처리
결론
Spring Data JPA에서 실행되는 순수 JPA 코드는 SimpleJpaRepository와 그 하위 쿼리 실행 계층에 존재하며 EntityManager의 생성 및 종료와 트랜잭션 제어는 Repository가 아닌 Spring JPA 인프라 계층에서 담당한다는 것을 확인했다. 즉, Spring Data JPA는 순수 JPA를 대체하는 것이 아니라, 순수 JPA의 사용 위치와 책임을 명확히 분리한 추상화 계층이다.
'개발 지식 > Spring boot' 카테고리의 다른 글
| [Spring boot] JPA - 순수 JPA 애플리케이션 개발(JPQL) (0) | 2026.01.30 |
|---|---|
| [Spring boot] JPA - 순수 JPA 프로젝트 설정(import 문제, 라이브러리 정리) (0) | 2026.01.30 |
| [Spring boot] Maven VS Gradle (0) | 2026.01.22 |
| [Spring boot] JPA - JPA가 왜 필요할까? (0) | 2026.01.22 |
| [Spring boot] 카카오 로그인 Oauth 2.0 (0) | 2025.01.05 |
