[Spring] JPA 기본 CRUD 동작 예제

2025. 8. 13. 19:53·Back end/Spring Project
반응형

JPA에서 제공하는 조회(Select), 등록(Insert), 수정(Update), 삭제(Delete) 기능은
모두 영속성 컨텍스트와 밀접하게 연관되어 있습니다.

 

예제를 통해 각 기능의 실행 흐름과 콘솔 로그 결과를 확인해보겠습니다.


1. 조회 – 1차 캐시 동작 확인

EntityManager는 조회 시 먼저 1차 캐시를 확인하고,
이미 같은 트랜잭션 내에서 조회한 엔티티라면 DB 쿼리를 실행하지 않습니다.

try {
    // 1차 캐시 테스트
    Member findMember1 = em.find(Member.class, 101L); // 첫 조회 → DB SQL 실행
    Member findMember2 = em.find(Member.class, 101L); // 두 번째 조회 → 1차 캐시에서 반환

    // 동일 객체인지 비교 (1차 캐시 활용 여부 확인)
    System.out.println("result = " + (findMember1 == findMember2));

    System.out.println("===============================");

    tx.commit();
} catch (Exception e) {
    tx.rollback();
}

💻 실행 결과

Hibernate: 
    select member0_.id as id1_0_0_, member0_.username as username2_0_0_ 
    from Member member0_ where member0_.id=?

result = true
===============================

📌 해설

  • 첫 번째 em.find() → DB 쿼리 실행 후, 영속성 컨텍스트 1차 캐시에 저장됩니다.
  • 두 번째 em.find() → DB를 조회하지 않고, 1차 캐시에서 동일 객체를 반환합니다.
  • findMember1 == findMember2 → true
    → 동일한 엔티티 인스턴스라는 것을 의미합니다.

2. 등록 – 쓰기 지연 (Transactional Write-Behind)

EntityTransaction transaction = em.getTransaction();
transaction.begin();

Member member1 = new Member(150L, "A");
Member member2 = new Member(160L, "B");

// 엔티티를 영속성 컨텍스트에 등록 (아직 DB에 INSERT SQL 전송 안 함)
em.persist(member1);
em.persist(member2);

System.out.println("===============================");

// 여기까지 INSERT SQL 실행 안 됨
transaction.commit(); // 커밋 시 SQL 실행

💻 실행 결과

===============================
Hibernate: 
    insert into Member (username, id) values (?, ?)
Hibernate: 
    insert into Member (username, id) values (?, ?)

📌 해설

  • persist()를 호출하면 엔티티는 영속 상태로 전환되지만,
    즉시 SQL이 실행되지 않고 쓰기 지연 저장소에 보관됩니다.
  • commit() 시점에 한꺼번에 INSERT SQL을 전송하여 DB I/O 성능을 최적화합니다.

3. 수정 – 변경 감지 (Dirty Checking)

JPA는 엔티티를 em.find()로 조회하여 영속 상태로 만든 뒤,
값을 변경하면 커밋 시점에 자동으로 UPDATE SQL을 실행합니다.

Member member = em.find(Member.class, 150L);
member.setName("ZZZZZ"); // 값 변경

System.out.println("===============================");

tx.commit(); // 변경 감지 후 UPDATE SQL 실행

💻 실행 결과

Hibernate: 
    select member0_.id as id1_0_0_, member0_.username as username2_0_0_ 
    from Member member0_ where member0_.id=?

===============================

Hibernate: 
    update Member set username=? where id=?

📌 해설

  • em.update() 같은 메서드가 없는 이유는, JPA가 변경 감지 기능을 지원하기 때문입니다.
  • 커밋 시점에 엔티티 스냅샷과 현재 값을 비교하여 변경된 필드만 UPDATE 합니다.

4. 삭제 – 엔티티 제거

Member memberA = em.find(Member.class, "memberA");
em.remove(memberA);

💻 실행 결과

Hibernate: 
    select member0_.id as id1_0_0_, member0_.username as username2_0_0_ 
    from Member member0_ where member0_.id=?

Hibernate: 
    delete from Member where id=?

📌 해설

  • 삭제 대상은 영속 상태여야 하므로, 먼저 find()로 조회해야 합니다.
  • remove() 호출 시 즉시 DELETE SQL이 실행되는 것이 아니라,
    커밋 시점에 실행됩니다.

📊 JPA 엔티티 상태 흐름 다이어그램

      [비영속] (new/transient)
            │
            │ em.persist()
            ▼
      [영속] (managed)  ←────────────┐
       │   ▲                        │
       │   │ em.find() or JPQL 조회 │
       │   │                        │
       │ em.detach(), clear(), close()
       ▼
   [준영속] (detached)
       │
       │ em.remove()
       ▼
      [삭제] (removed)

📌 정리

  • 조회: 1차 캐시 활용, 동일 PK 재조회 시 DB 접근 없음
  • 등록: 쓰기 지연을 통해 커밋 시 INSERT SQL 실행
  • 수정: 변경 감지로 UPDATE SQL 자동 실행
  • 삭제: 조회 후 remove() 호출 시 DELETE SQL 실행

 

반응형

'Back end > Spring Project' 카테고리의 다른 글

[Spring] JPA 준영속 상태(Detached)  (0) 2025.08.15
[Spring] JPA flush  (0) 2025.08.14
[Spring] Maven profile 이용한 환경별 (local, dev, prod) 빌드 및 설정 분리  (0) 2025.07.23
[Spring] BeanFactory와 ApplicationContext  (0) 2025.07.17
[Spring] AnnotationConfigApplicationContext로 알아보는 스프링 컨테이너 생성 과정  (0) 2025.07.15
'Back end/Spring Project' 카테고리의 다른 글
  • [Spring] JPA 준영속 상태(Detached)
  • [Spring] JPA flush
  • [Spring] Maven profile 이용한 환경별 (local, dev, prod) 빌드 및 설정 분리
  • [Spring] BeanFactory와 ApplicationContext
Kim-SooHyeon
Kim-SooHyeon
개발일기 및 알고리즘, 블로그 운영에 대한 글을 포스팅합니다. :) 목표: 뿌리 깊은 개발자 되기
    반응형
  • Kim-SooHyeon
    soo_vely의 개발로그
    Kim-SooHyeon
  • 전체
    오늘
    어제
    • 분류 전체보기 (258)
      • 알고리즘 (108)
        • 자료구조 (3)
        • Java (104)
        • Python (1)
      • Back end (73)
        • Spring Project (28)
        • Java (23)
        • API (1)
        • Python (0)
        • Django (3)
        • Linux (1)
        • 서버 (2)
        • 에러로그 (11)
        • 부스트 코스 (1)
      • Front end (9)
        • HTML, CSS (4)
        • JavaScript (4)
        • JQuery (0)
      • 기타 프로그래밍 (4)
        • Android Studio (1)
        • Arduino (2)
        • Azure Fundamental(AZ-900) (1)
      • 개발도구 (24)
        • IntelliJ (2)
        • Git (12)
        • SVN (0)
        • Eclipse (2)
        • 기타 Tool (8)
      • Database (17)
        • Oracle (11)
        • MySQL (0)
        • H2 Database (3)
        • ORM & JPA (1)
      • 자격증 (10)
        • 컴활 1급 (7)
        • 컴활 2급 (2)
        • SQLD (1)
      • 기타 (13)
        • 블로그 운영 (6)
        • 문서 (1)
        • 기타 (6)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    springboot
    단계별풀기
    1차원 배열
    Oracle
    BOJ
    오라클
    solved.ac
    for문
    java
    배열
    spring
    Git
    github
    문자열
    백준 자바
    구현
    jpa
    백준알고리즘
    백준
    알고리즘
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
Kim-SooHyeon
[Spring] JPA 기본 CRUD 동작 예제
상단으로

티스토리툴바