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 사용 시 주의할 점

  1. N+1 문제
    • 연관 관계에서 LAZY를 무분별하게 사용하면 발생
    • 해결: fetch join, @EntityGraph, BatchSize 등 활용
  2. 지연 로딩과 즉시 로딩
    • LAZY: 필요한 순간 쿼리 실행 (권장)
    • EAGER: 무조건 같이 조회 (성능 주의)
  3. 무한 루프 문제 (양방향 연관관계)
    • toString(), JSON 변환 시 StackOverflow 발생 가능
    • 해결: @JsonIgnore, DTO 분리
  4. 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