영속성 컨텍스트(Persistence Context)는 JPA에서 매우 중요한 개념으로, 엔티티(Entity) 객체를 관리하고 영속성을 유지하는 1차 캐시 역할을 하는 저장소입니다. 이를 통해 데이터베이스와 애플리케이션 간의 효율적인 상호작용을 지원합니다.
1. 영속성 컨텍스트란?
- JPA에서 **엔티티 매니저(EntityManager)**가 관리하는 논리적인 저장 공간.
- 애플리케이션과 데이터베이스 사이에서 엔티티 객체를 캐싱하여 데이터 변경 및 조회를 관리.
- 엔티티 객체의 생명 주기(lifecycle)를 관리함.
2. 엔티티의 생명 주기
엔티티 객체는 다음 4가지 상태를 가질 수 있습니다:
1) 비영속(Transient)
- 영속성 컨텍스트와 전혀 관계가 없는 상태.
- 단순히 new 키워드로 생성된 상태.
- 데이터베이스와 동기화되지 않음.
Member member = new Member(); // 비영속 상태
2) 영속(Managed)
- 영속성 컨텍스트에 의해 관리되는 상태.
- 데이터베이스와 동기화 가능하며, 자동으로 변경 사항을 감지하여 업데이트.
EntityManager em = ...;
Member member = new Member();
em.persist(member); // 영속 상태로 전환
3) 준영속(Detached)
- 영속성 컨텍스트에서 분리된 상태.
- 더 이상 영속성 컨텍스트가 관리하지 않음.
- 변경 사항이 데이터베이스에 반영되지 않음.
em.detach(member); // 준영속 상태로 전환
4) 삭제(Removed)
- 영속성 컨텍스트에서 제거된 상태.
- 트랜잭션이 커밋되면 데이터베이스에서도 삭제됨.
em.remove(member); // 삭제 상태
3. 영속성 컨텍스트의 주요 기능
1) 1차 캐시
- 동일한 트랜잭션 내에서 같은 엔티티를 조회하면 데이터베이스가 아닌 영속성 컨텍스트에서 데이터를 반환.
- 성능 최적화를 위해 사용됨.
Member member1 = em.find(Member.class, 1L); // 데이터베이스에서 조회
Member member2 = em.find(Member.class, 1L); // 1차 캐시에서 조회
2) 변경 감지(Dirty Checking)
- 영속 상태의 엔티티 객체가 변경되면, 트랜잭션이 커밋될 때 자동으로 UPDATE 쿼리를 실행.
Member member = em.find(Member.class, 1L);
member.setName("Updated Name"); // 변경 감지
// 트랜잭션 커밋 시 UPDATE 쿼리 실행
3) 쓰기 지연(Batch Processing)
- 영속성 컨텍스트는 persist() 호출 시 즉시 데이터베이스에 저장하지 않고, **쓰기 지연(SQL 저장소)**에 쿼리를 모아둠.
- 트랜잭션 커밋 시점에 일괄 처리로 SQL 실행.
em.persist(member1);
em.persist(member2);
// 트랜잭션 커밋 시점에 INSERT 쿼리 실행
4) 동일성 보장
- 동일한 영속성 컨텍스트 내에서는 같은 식별자를 가진 엔티티 객체를 항상 동일하게 보장.
Member member1 = em.find(Member.class, 1L);
Member member2 = em.find(Member.class, 1L);
System.out.println(member1 == member2); // true
4. 영속성 컨텍스트의 범위
- 트랜잭션 범위: 기본적으로 영속성 컨텍스트는 트랜잭션 단위로 동작.
- 확장된 범위: 특별히 설정하면 트랜잭션이 아닌 애플리케이션 컨텍스트 단위로 유지.
5. 영속성 컨텍스트의 이점
- 데이터베이스 접근 최소화로 성능 최적화.
- 객체 변경 사항을 자동으로 감지하여 업데이트.
- 트랜잭션 단위의 데이터 일관성 보장.
- 코드의 가독성과 유지보수성 향상.
6. 주의 사항
- 메모리 관리: 너무 많은 엔티티를 영속성 컨텍스트에 저장하면 메모리 부족 문제 발생 가능.
- 준영속 상태: 영속성 컨텍스트에서 분리된 객체는 자동 업데이트가 이루어지지 않으므로 개발자가 명시적으로 merge()를 호출해야 함.
정리) 영속성 컨텍스트는 JPA가 데이터베이스와 객체 사이의 복잡한 변환 과정을 간단하게 처리할 수 있도록 돕는 중요한 메커니즘입니다. 이를 이해하면 더 효율적이고 안전한 데이터 처리가 가능합니다!
'Spring > Spring JPA' 카테고리의 다른 글
[JPA] Spring JPA 관련 yml 설정의 주요 항목 (0) | 2024.12.04 |
---|---|
[JPA] spring.jpa.properties.hibernate.dialect (0) | 2024.12.04 |
[JPA]@ManyToOne 필드에 @ToString.Exclude 붙이는 이유 (0) | 2024.11.28 |
[JPA] JPA에서 관계를 매핑할 때 사용하는 어노테이션 (0) | 2024.11.27 |
[JPA]@ToString.Exclude (0) | 2024.11.25 |