[SPRING] JPA - 영속성 컨텍스트

림민지·2025년 3월 29일

Today I Learn

목록 보기
36/62

JPA
: Java의 ORM 기술 표준(인터페이스)
객체와 RDB 간의 매핑을 자동으로 처리 → 패러다임 불일치 문제 해결

JPA를 사용하는 이유

  1. 생산성 향상
    SQL을 직접 작성하지 않고, persist(), find(), remove()` 같은 메서드로 간단하게 데이터를 조작할 수 있다.
jpa.persist(tutor);
Tutor tutor = jpa.find(Tutor.class, tutorId);
tutor.setName("새로운 이름");
jpa.remove(tutor);
  1. 유지보수성 증가
    객체 필드가 변경되어도 JPA가 자동으로 SQL을 생성하므로, 직접 SQL을 수정할 필요가 없음

  2. 패러다임 불일치 문제 해결
    JPA는 @Inheritance 전략을 통해 테이블을 자동으로 매핑할 수 있다.

  3. 연관관계
    JPA의 @ManyToOne, @OneToMany 등을 사용하여 객체 간 참조를 쉽게 설정

  4. 객체 그래프 탐색
    fetch join을 사용하여 한 번의 SQL 실행으로 필요한 데이터를 모두 불러올 수 있다.

  5. 객체 비교
    동일한 트랜잭션 내에서는 find()를 호출해도 같은 인스턴스를 반환하므로, == 비교 연산이 true

  6. 성능 최적화
    -동일한 트랜잭션 내에서는 같은 객체를 재사용하여 성능을 최적화합니다.
    -지연 로딩(Lazy Loading)
    → 필요한 시점에만 데이터를 조회, 불필요한 SQL 실행을 방지!!

  7. ⭐️Hibernate
    데이터베이스와 Hibernate가 상호작용할 때 특정 데이터베이스에 맞게 SQL 구문을 자동으로 조정 (어떤 DB언어를 사용하던지 알아서 번역해줌)


❤️‍🔥 영속성 컨텍스트 Persistence Context

: JPA에서 엔티티 객체를 관리하는 1차 캐시(메모리 영역)
➡️ EntityManager가 엔티티를 CRUD할때 이를 관리해준다
➡️ 트랜잭션 범위 내에서 엔티티의 상태를 추적하고, 필요하면 DB와 동기화까지!

1. 엔티티 상태 & 동일성 보장

엔티티의 생명주기(상태) 4가지

상태설명
비영속JPA가 관리하지 않는 객체
영속영속성 컨텍스트에서 관리되는 객체
준영속관리가 해제된 객체
삭제삭제될 객체 → DB에서도 삭제

🔗 동일성 보장
: 같은 EntityManager에서 같은 엔티티를 여러번 조회하면 동일한 객체를 반환한다!
→ 1차 캐시 덕분

@Entity
class Member {
    @Id @GeneratedValue
    private Long id;
    private String name;
}
//2번 선언해도 동일성 보장 덕분에 같은 객체를 반환하게 됨
Member member1 = em.find(Member.class, 1L);
Member member2 = em.find(Member.class, 1L);

System.out.println(member1 == member2); // true (같은 인스턴스)

두번 조회해도 DB에서 다시 가져오는게 아니고, 1차 캐시에서 반환되는 것

2. 쓰기 지연 Write-Behind

: JPA는 트랜잭션이 커밋될 때까지 Insert Update를 모아서 한 번에 처리함

em.persist(new Member("Alice"));
em.persist(new Member("Bob"));
System.out.println("SQL 실행 전"); // 여기까지 SQL 실행 X

em.flush(); // 강제 실행
System.out.println("SQL 실행 후"); // 여기서 SQL 실행됨

➡️ persist()를 호출해도 바로 SQL 실행❌, "영속성 컨텍스트"에 저장
➡️ flush() or 트랜잭션이 커밋될 때 한꺼번에 DB에 반영

3. 변경 감지

: 엔티티가 영속상태면, JPA는 자동으로 변경을 감지해 Update 실행함
→ 즉 em.update() 같은 명령 호출하지 않아도 알아서 처리함

Member member = em.find(Member.class, 1L); // 1차 캐시에서 조회
member.setName("Charlie"); // setter로 값 변경 

// 트랜잭션 커밋 시점에 자동으로 UPDATE 실행
em.getTransaction().commit();

트랜잭션 커밋 시점자동으로 UPDATE SQL 실행
=> 따로 update() 호출 안해도 JPA가 알아서 반영해주는것!!

4. flush()

: 1차 캐시는 유지하면서 영속성 컨텍스트의 변경 내용을 DB와 동기화하는 과정

💡 flush()가 발생하는 시점
1. 트랜잭션 커밋할 때 (commit())
2. JPQL 실행 직전 (Query 실행 전)
3. em.flush() 호출했을 떄

Member member = new Member("David");
em.persist(member);  // SQL 실행 X
em.flush();          // 강제 실행 (SQL 즉시 실행)

.clear() 호출하지 않으면 영속 상태는 유지된다!


🏁 정리하기

키워드하는 일
영속성 컨텍스트JPA가 엔티티를 관리하는 메모리 공간 (=1차 캐시)
엔티티 상태영속, 비영속, 준영속, 삭제
동일성 보장 같은 EntityManager에서 같은 엔티티 부르면, 재사용함(동일한 인스턴스 가져옴)
쓰기 지연persist() 했다고 바로 INSERT하는게 아니라, 트랜잭션 시 한번에 실행함
변경 감지세터로 값을 변경하면, JPA가 자동으로 업뎃해줌
flush()영속성 컨텍스트의 바뀐 내용을 DB에 즉시 반영해줌

⭐️ 영속성 컨텍스트를 통해
성능 최적화, 동일성 보장, 자동 변경 감지 등의 핵편한 기능 제공
쓰기 지연 & 변경 감지 ➡️ 불필요한 SQL↓ & 성능↑

profile
@lim_128

0개의 댓글