JPA => 설계 (: 엔티티와 테이블을 매핑) + 활용 (: 매핑한 엔티티 실제 사용)
활용 => 엔티티 매니저 & 영속성 컨텍스트
엔티티 매니저 팩토리 makes 엔티티 매니저
엔.매.팩 은 여러 스레드가 동시에 접근해도 안전 하므로 서로 다른 스레드 간에 공유 OK
엔.매 는 여러 스레드가 동시에 접근하면 동시성 문제가 발생하므로 공유 X
동시성 문제
동일한 하나의 데이터에 2개 이상의 스레드, 혹은 세션에서 가변 데이터를 동시에 제어할 때 나타나는 문제
하나의 세션이 데이터를 수정중일 때, 다른 세션에서 수정 전의 데이터를 조회해 로직을 처리함으로써 데이터의 정합성이 깨지는 문제
JPA는 데이터베이스에 접근할 때 데이터베이스 커넥션을 사용함. 그러나 JPA는 직접 커넥션 객체를 다루지 않고, EntityManager를 통해 데이터베이스와 상호작용
엔티티 매니저는 보통 트랜잭션 시작할 때 커넥션 획득, 데이터베이스 연결이 필요하지 않으면 커넥션 얻지 않음
이때 엔티티 매니저는 커넥션 객체를 통해서 데이터베이스와 상호작용을 함
커넥션 객체
역할
● 데이터 베이스 연결 : 실제로 데이터베이스에 연결하여 SQL 명령을 실행하고 결과 반환
● 트랜잭션 관리 : 커넥션은 트랜잭션을 관리하며, 이는 JPA의 EntityManager가 내부적으로 처리
문제점
DB 연결할 때마나 connection 객체를 새로 만드는 것은 비용이 많이 들고, 비효율적임
↓
커넥션 풀
애플리케이션 로딩 시점에 Connection 객체를 미리 생성, 애플리케이션에 DB연결 필요 시 미리 준비된 Connection 객체를 사용하여 애플리케이션 성능을 향상시킴
엔티티의 생명주기
● 비영속 (new/transient) : 영속성 컨텍스트와 전혀 관계가 없는 상태
● 영속 (managed) : 영속성 컨텍스트에 저장된 상태 = 영속성 컨텍스트에 의해 관리된다
● 준영속 (detached) : 영속성 컨텍스트에 저장되었다가 분리된 상태
● 삭제 (removed) : 삭제된 상태
영속성 컨텍스트 (Persistence Context)
: 엔티티를 영구 저장하는 환경
엔티티 매니저 = 영속성 컨텍스트에 엔티티 보관 및 관리
- 여러 엔티티 매니저가 같은 영속성 컨텍스트 접근 가능
- 엔티티 매니저 생성 시 하나 만들어짐
persist() : 엔티티 매니저를 사용해서 회원 엔티티를 영속성 컨텍스트에 저장
특징
● 엔티티를 식별자 값(@Id)으로 구분 → 영속 상태는 식별자 값이 반드시 존재해야함
● 플러시를 통해 데이터베이스에 저장
장점
● 1차 캐시
: 영속성 컨텍스트가 가지고 있는 내부 캐시. 영속 상태의 엔티티는 모두 이곳에 저장됨. 키는 식별자 값임
● 동일성 보장
● 트랜잭션 지원하는 쓰기 지연 (transactional write-behind)
: 트랜잭션 커밋 전까지는 쿼리 저장소에 모아두다가 커밋 시에 모아둔 쿼리를 데이터베이스에 보냄
엔티티 삭제의 경우, em.remove(data)를 호출하는 순간 data는 영속성 컨텍스트에서 제거됨!
플러시
: 영속성 컨텍스트의 변경 내용을 데이터베이스에 동기화하는 작업. 이때 등록, 수정, 삭제한 엔티티를 데이터베이스에 반영함.
= 쓰기 지연 SQL 저장소에 모인 쿼리를 데이터베이스에 보냄
● 발생 시점
○ em.flush() 호출
○ 트랜잭션 커밋 시
○ JPQL 쿼리 실행 시
↓
이를 변경하고 싶다면, javax.persistence.FlushModeType 사용
○ FlushModeType.AUTO : 커밋 & 쿼리 실행 시 (Default)
○ FlushModeType.COMMIT : 커밋할 때만
● 변경 감지 (dirty-checking)
: 엔티티의 변경사항을 데이터베이스에 자동으로 반영하는 기능. 영속 상태의 엔티티에만 적용
스냅샷 : 최초 상태를 복사해서 저장해두는 것 → 플러시 시점에 스냅샷과 엔티티를 비교해서 변경사항 수정 쿼리 작성
이때 default = 엔티티의 모든 필드 업데이트 (항상 쿼리 동일하게 유지)
동적 update-sql 생성하고 싶다면, DynamicUpdate 혹은 DynamicInsert 하이버에이트 확장 기능 이용
● 지연 로딩
준영속
: 영속성 컨텍스트가 제공하는 기능 사용 불가능
특징
● 식별자 값을 가지고 있음 : 이미 한 번 영속 상태였으므로 반드시 식별자 값을 가지고 있음
● 지연 로딩을 할 수 없음
준영속 상태로 만드는 법
● em.detach(entity) : 특정 엔티티만 준영속 상태로 전환
이 메소드를 호출하는 순간 1차 캐시부터 쓰기 지연 SQL 저장소까지 해당 엔티티를 관리하기 위한 모든 정보가 제거됨.
● em.clear() : 영속성 컨텍스트를 완전히 초기화 (= 해당 영속성 컨텍스트의 모든 엔티티를 준영속 상태로 만듬)
● em.close() : 영속성 컨텍스트 종료
em.clear() 와 em.close() 의 차이
clear()의 경우 트랜잭션이 유지되지만, em.close()의 경우 트랜잭션이 종료되며 해당 entityManager의 인스턴스도 더 이상 사용할 수가 없음
병합: merge()
:: 준영속/비영속 상태의 엔티티를 영속 상태로 변경 'save or update'
merge()는 준영속 상태의 엔티티 정보를 가지고 새로운 영속 상태 엔티티를 반환 (= 다른 인스턴스)
○ 준영속화 시켜서 준영속 상태에서 엔티티를 수정하고 병합(merge)하면 반영되지 않았던 변경 사항이 다시 영속성 컨텍스트에 반영됨
○ 파라미터로 넘어온 엔티티는 병합 후에도 준영속 상태로 남아있음
출처
https://product.kyobobook.co.kr/detail/S000000935744
자바 ORM 표준 JPA 프로그래밍 | 김영한 - 교보문고
자바 ORM 표준 JPA 프로그래밍 | 자바 ORM 표준 JPA는 SQL 작성 없이 객체를 데이터베이스에 직접 저장할 수 있게 도와주고, 객체와 관계형 데이터베이스의 차이도 중간에서 해결해준다. 이 책은 JPA
product.kyobobook.co.kr
참고
커넥션 풀이란 (Connection Pool)
1) 커넥션 풀 (Connection Pool) (1) 커넥션 풀이란 JDBC API를 사용하여 데이터베이스와 연결하기 위해 Connection 객체를 생성하는 작업은 비용이 굉장히 많이 드는 작업 중 하나이다. Connection 객체를 생성
shuu.tistory.com
'Spring' 카테고리의 다른 글
연관관계 매핑(1) (0) | 2025.04.05 |
---|---|
내 첫 스프링 CRUD 만들기 (0) | 2025.04.04 |
이펍 세미나(1) (0) | 2025.04.01 |
엔티티 매핑 (0) | 2025.03.30 |
JPA 프로그래밍 (1) | 2025.03.16 |