Back_End/JPA
Spring Data JPA란?
10Biliion
2025. 4. 11. 13:23

Spring Data JPA는 JPA를 더 간편하게 사용할 수 있도록 도와주는 Spring 프로젝트이다.
기존 JPA에서는 EntityManager를 직접 사용했지만, Spring Data JPA는 인터페이스만 정의하면 구현 없이도 CRUD 기능을 자동 제공한다.
public interface UserRepository extends JpaRepository<User, Long> {
List<User> findByName(String name); // 자동으로 구현됨
}
JpaRepository를 상속하면 save(), findAll(), deleteById() 등 기본 메서드들을 제공받는다.
장점
- 코드가 간결해지고
- 쿼리 메서드로 자동 SQL 생성
- 커스텀 쿼리는 @Query로 처리 가능
[ JPA Entity 생명주기 ]
JPA의 Entity 객체는 총 4가지 상태를 가진다.
상태 | 설명 |
New | 아직 DB에 저장되지 않은 상태 (new User()) |
Managed | persist() 또는 find()로 영속성 컨텍스트에 포함된 상태 |
Detached | 영속성 컨텍스트에서 분리된 상태 (em.detach(), 트랜잭션 종료 시 등) |
Removed | 삭제 예약 상태 (em.remove() 호출) |
생명주기 예시
User user = new User(); // New
em.persist(user); // Managed
em.detach(user); // Detached
em.remove(user); // Removed
트랜잭션 범위
JPA는 트랜잭션 안에서 동작해야만 올바르게 작동한다.
특히 **변경 감지 (Dirty Checking)**나 쓰기 지연 (Write Behind) 등은 트랜잭션 없이 동작하지 않는다.
@Transactional
public void updateUser(Long id, String newName) {
User user = userRepository.findById(id).orElseThrow();
user.setName(newName); // 여기서 수정
// save() 호출 안 해도 변경됨 → 트랜잭션 커밋 시점에 flush()
}
트랜잭션 커밋 시점에 변경된 내용이 감지되어 UPDATE 쿼리가 실행됨.
QueryDSL vs Native Query
구분 | 설명 |
JPQL | JPA에서 제공하는 객체 지향 쿼리 언어 ("SELECT u FROM User u WHERE u.name = :name") |
Native Query | DB에 직접 SQL 작성 ("SELECT * FROM users WHERE name = ?"). 복잡한 쿼리에 사용 |
QueryDSL | Java 코드로 쿼리 작성하는 타입 안전한 DSL |
Native Query 예시
@Query(value = "SELECT * FROM users WHERE name = :name", nativeQuery = true)
List<User> findByNameNative(@Param("name") String name);
QueryDSL 예시
QUser user = QUser.user;
List<User> result = queryFactory
.selectFrom(user)
.where(user.name.eq("홍길동"))
.fetch();
QueryDSL 장점
- 컴파일 시점에 오류 검출 가능
- 복잡한 조건/조인도 자바 코드로 표현
- 실무에서 복잡한 검색, 동적 쿼리에 많이 사용됨
JPA 사용 시 주의할 점
- N+1 문제
- 연관 관계에서 LAZY를 무분별하게 사용하면 발생
- 해결: fetch join, @EntityGraph, BatchSize 등 활용
- 지연 로딩과 즉시 로딩
- LAZY: 필요한 순간 쿼리 실행 (권장)
- EAGER: 무조건 같이 조회 (성능 주의)
- 무한 루프 문제 (양방향 연관관계)
- toString(), JSON 변환 시 StackOverflow 발생 가능
- 해결: @JsonIgnore, DTO 분리
- DB 락 주의
- @Version을 사용한 낙관적 락 or PESSIMISTIC_WRITE로 비관적 락 제어 가능

구분 | 설명 |
ORM | 객체 <-> 테이블 자동 매핑 |
Hibernate | 가장 널리 쓰이는 ORM 구현체 |
JPA | Java ORM 표준, Hibernate가 대표 구현체 |
Spring Data JPA | JPA를 더 쉽게 쓰기 위한 Spring 프로젝트 |
QueryDSL | Java 코드로 쿼리 작성하는 DSL |
트랜잭션 | JPA는 반드시 트랜잭션 안에서 작동 |
Entity 생명주기 | New → Managed → Detached → Removed |