영속성 컨텍스트
엔티티를 영구 저장하는 환경
DB를 영속성 컨텍스트라는 곳 안에 저장하는 것
- 영속성 켄텍스트는 논리적인 개념
- 엔티티매니저를 통해 영속성 컨텍스트에 접근
엔티티의 생명주기
- 비영속성 :
- 영속성 컨텍스트와 상관없는 상태 (저장할 객체를 생성한 상태)
- 영속 :
- 영속성 컨텍스트에 관리되는 상태
- 엔티티 매니저를 통해 객체를 넣은 상태 (저장시점 or SELECT쿼리를 통해 찾아와서 엔티티 매니저에 들어가 관리되는 경우) 커밋 전에 쿼리를 몰아두었다가 커밋되는 시점에 한번에 쿼리가 날라감.
- 준영속 : 영속성 컨텍스트에 저장되었다가 분리되는 상태
- 삭제 : 삭제된 상태
영속성 컨텍스트의 이점
- 1차 캐시
- 동일성(identity) 보장
- 트랜잭션을 지원하는 쓰기 지연
- 변경 감지
- 지연로딩
조회 시 1차 캐쉬에서 먼저 찾아오는 우선권을 갖는다. 1차 캐쉬에 없다면 DB에서 저장하여 온 후 1차 캐쉬에 저장하고 반환함
엔티티 수정(변경 감지)
수정 시 entity.set인스턴스 로 업데이트 할 수 있다.
수정시 새로 저장하지 않고 인스턴스 값을 다시 Set해준다. 이유는 엔티티매니저는 1차캐쉬안에 ID,Entity,스냅샷을 가지고 있다. 만일 엔티티를 변경하여 커밋하게 된다면 1차캐쉬 내의 스냅샷과 커밋된 엔티티를 비교하여 수정이 감지된다면 업데이트 쿼리를 날린다.
플러쉬(flush)
영속성 컨텍스트의 변경 내용을 데이터베이스에 반영
- 변경감지
- 수정된 엔티티 쓰기 지연SQL 저장소에 등록
- 쓰기 지연 SQL(등록, 수정 삭제 쿼리) 를 데이터베이스에 전송
- 영속성 컨텍스트를 비우는게 아니라 변경내용을 데이터베이스에 동기화 시킨다.
**플러쉬 호출 상황**
- em.flush() - 직접 호출
- 트랜잭션 커밋 - 플러쉬 자동 호출
- JPQL쿼리 실행 - 플러쉬 자동 호출
**JPQL의 경우 쿼리문을 통해 DB에 접근해 데이터를 가져 온다. 따라서 같은 트랜젝션 내에서 저장과 JPQL을 통한 조회가 동시에 일어난다면 찾아올 수 없다. 이런 상황을 대비해 JPQL은 실행시 플러쉬를 자동으로 호출한다.**
준영속 상태
영속 -> 준영속 (엔티티 매니저가 관리하던 객체가 제거됨)
영속상태의 엔티티가 영속성 컨텍스트에서 분리됨
영속성 컨텍스트가 제공하는 기능을 못함.
- em.detach(객체); - 특정 객체만 영속성 제거
- em.clear(); - 1차 캐쉬에 있는 모든 영속성이 부여된 객체를 제거 완전 초기화
- em.close(); - 영속성 컨텍스트를 종료
객체와 테이블 매핑(@Entity, @Table)
@Entity :
해당 에노테이션이 붙은 클래스는 JPA가 관리, 엔티티라 한다.
**주의**
- 기본 생성자 필수(파라미터가 없는 public또는 protected생성자)
- final 클래스, enum, interface, inner 클래스 사용 X
- 저장할 필드에 final 사용 X
@Table :
엔티티와 매핑할 테이블 지정
- name : 테이블 이름
- catalog : 데이터베이스 catalog 매핑
- schema : 데이터베이스 schema 매핑
- uniqueConstraints(DDL) : DDL 생성시에 유니크 제약조건 생성
데이터베이스 스키마 관련 설정
DDL을 어플리케이션 생성시 자동으로 실행
아래 설정을 추가하면 엔티티를 기반으로 DB테이블을 자동으로 생성/ 생성후 삭제/ 업데이트/ 정상매핑 확인 한다.
- <property name="hibernate.hbm2ddl.auto" value="create" /> : 동일한 이름의 테이블을 삭제하고 생성함
- <property name="hibernate.hbm2ddl.auto" value="create-drop" /> : 테이블을 생성하고 종료되면 삭제함
- <property name="hibernate.hbm2ddl.auto" value="update" /> : 변경 분만 반영하고자 할 때
- <property name="hibernate.hbm2ddl.auto" value="validate" /> : 정상 매핑되었는지 확인할 때
@Column
- name : 해당 인스턴스와 매핑된 DB의 컬럼명을 지정함
- unique : 유니크 제약조건을 넣어줌
- length : 길이 제약 조건 넣어줌
- insertble : 등록 가능 여부 (true, false)
- updatable : 변경 가능 여부 (true, false)
- nullable : null값의 허용 여부 설정
- columnDefinition : 컬럼의 타입을 직접 지정할 수 있다.
- EnumType : Ordinal = 순서 값 , String = 문자열
** Enum 안에서 순서가 변경된다면 동일값 값이더라도 DB테이블에 저장될 때 다른 순서 인덱스가 저장됨으로 String으로 사용하는것을 권장. **
PK값 생성 전략
@GeneratedValue(strategy = GenerationType.IDENTITY)
:MySQL 환경에서 많이 사용
DB가 기본키를 생성하도록 위임
엔티티는 PK값을 가지고 있을때 영속성 컨텍스트로 등록이 가능하다
하지만 Identity전략의 경우 PK 값을 DB가 생성하도록 위임하기 때문에 JPA는 해당 데이터를 커밋하기 전에 PK를 알수 없다. 때문에 Identity전략의 경우 persist가 호출되면 즉시 INSERT 쿼리를 날라간다.
@GeneratedValue(strategy = GenerationType.SEQUENCE)
:Oracle 환경에서 많이 사용
시퀀스 값을 가져와 기본키를 세팅
시퀀스를 관리하는 테이블에서 다음값을 받아옴(다음값이 PK로 설정될 것이기 때문에)
받아온 시퀀스 값을 INSERT값에 넣고 한번에 커밋한다.
@GeneratedValue(strategy = GenerationType.TABLE)
:키 생성 전용 테이블을 하나 만들어 데이터 베이스 시퀀스를 흉내냄, 모든 데이터 베이스에 사용 가능하지만, DB테이블을 하나 만듬으로 성능이 떨어짐
initialValue=1, allocationSize=50
identity가 아닌 전략에서 사용되는 설정으로 키를 생성 할 때 일정량의 시퀀스 개수를 가져와 메모리에 저장하여 하나씩 가져다가 쓴다. 네트워크 최적화가 가능하다. 기본설정은 50개의 시퀀스를 가져와 메모리에 올려놓고 하나씩 가져다 쓴다.
기본 키 제약 조건은 아래와 같다.
- null아님
- 유일
- 값이 변하면 안됨
'JPA' 카테고리의 다른 글
@MappedSuperclass (0) | 2022.12.20 |
---|---|
상속관계 매핑 (0) | 2022.12.20 |
연관관계 매핑 (0) | 2022.12.20 |
연관관계 매핑 기초 (0) | 2022.12.19 |
JAP 기본 원리 및 사용하는 이유 (1) | 2022.12.15 |