Reference. 자바 ORM 표준 JPA 프로그래밍
책 목차 및 이전 글
더보기
- 영속성 컨텍스트와 식별자 값
- 엔티티를 식별자 값(
@Id
로 테이블의 기본키와 매핑한 값)으로 구분
- 영속 상태는 식별자 값이 반드시 필요 (없으면 예외 발생)
- 엔티티를 식별자 값(
- 영속성 컨텍스트와 데이터베이스 저장
플러시(flush)
: JPA는 보통 트랜잭션을 커밋하는 순간
영속성 컨텍스트에 새로 저장된 엔티티를 데이터베이스에 반영
- 영속성 컨텍스트가 엔티티를 관리하면 좋은 장점
- 1차 캐시
- 동일성 보장
- 트랜잭션을 지원하는 쓰기 지연
- 변경 감지
- 지연 로딩
3.4.1 엔티티 조회
- 1차 캐시: 영속성 컨텍스트의 내부 캐쉬를 의미
- 영속 상태의 엔티티는 모두 이곳에 저장
- ex) 영속성 컨텍스트 내부에 Map이 있고 키는 @Id의 식별자, 값은 인스턴스
// 엔티티를 생성한 상태(비영속)
Member member = new Member();
member.setId(100L);
member.setUsername("회원1");
// 엔티티 영속
em.persist(member);
- 영속성 컨텍스트에 데이터를 저장, 조회하는 모든 기준은 데이터베이스 기본 키 값
Member member = em.find(Membr.class, "member1"); //"member1" 엔티티 식별자 값(key값)
조회 실행순서
em.find()
호출
- 1차 캐시에 엔티티를 검색
- 1차 캐시에 존재 하지 않으면 데이터베이스 조회
1차 캐시에서 조회
- 코드실행로 보는 실행 순서
Member member = new Member();
member.setId(100L);
member.setUsername("회원1");
// 1차 캐시에 저장됨
em.persist(member);
// 1차 캐시에서 조회
Member findMember = em.find(Member.class, 100L);
데이터베이스에서 조회
- 1차 캐시에 없으면 엔티티 매니저는 데이터베이스 조회 후 엔티티를 생성
- 1차 캐시에 저장한 후 영속 상태의 엔티티를 반환
그림의 실행 순서
em.find(Member.class, "member2")
를 실행
member2
가 1차 캐시에 없으므로 데이터베이스 조회
- 조회한 데이터를
member2
엔티티 생성 후 1차 캐시에 저장(영속 상태)
- 조회한 엔티티 반환
영속 엔티티의 동일성 보장
- 영속성 컨텍스트는 1차 캐시에 있는 같은 엔티티 인스턴스를 반환
- 영속성 컨텍스트는 성능상 이점과 엔티티 동일성을 보장 * 동일성, 동등성 [ 1.2.4 비교 ] 참조
Member a = em.find(Member.class, "member1");
Member b = em.find(Member.class, "member1");
System.out.println(a == b); // 동일성 인스턴스 비교, 동등성 값 비교
3.4.2 엔티티 등록
- 엔티티 매니저는 트랜잭션 커밋하기 직전까지 내부 쿼리 저장소에 insert SQL을 저장
- 트랜잭션 커밋할 때 모아둔 쿼리를 데이터베이스에 실행, 이것을 쓰기 지연
그림 실행 순서
- 엔티티 매니저는 1차 캐시에 회원 엔티티를 저장 후, insert SQL을 SQL 저장소에 보관
- 트랜잭션을 커밋하면 엔티티 매니저는 영속성 컨텍스트를
플러시
플러시
: 영속성 컨텍스트의 변경 내용을 데이터베이스에 동기화하는 작업
- 등록, 수정, 삭제를 반영 → 쓰기 지연 SQL 저장소에 모인 쿼리를 반영
트랜잭션을 지원하는 쓰기 지연이 가능한 이유
begin(); //트랜잭션 시작
save(A);
save(B);
save(C);
commit(); //트랜잭션 커밋
로직을 실행하는 2가지 방법
1. 데이터를 저장하는 즉시 등록 쿼리를 데이터 베이스로 이동 마지막에 트랜잭션을 커밋
2. 데이터를 메모리에 저장, 모아둔 등록 쿼리를 데이터베이스에 보낸 후 커밋
- 둘의 결과는 동일, 커밋 직전에만 데이터베이스에 SQL을 전달하면 결과는 동일
- 이것이 트랜잭션을 지원하는 쓰기 지연이 가능한 이유
- 모아둔 등록 쿼리를 한번에 전달해서 성능을 최적화 가능
3.4.3 엔티티 수정
SQL 수정 쿼리의 문제점
- 요구사항이 늘어나며 수정 쿼리도 점점 추가
- 기존에는 각각의 UPDATE 쿼리를 작성하거나, 하나의 합쳐진 UPDATE 쿼리를 사용
→ 합쳐진 UPDATE 쿼리는 예상치 못한 상황을 발생, 상황에 따라 UPDATE를 계속 추가 했음
- 수정 쿼리가 많아지고, 로직 분석을 위해 SQL확인 필요하게 되고 SQL의 의존적이게 됌
변경 감지
- 엔티티를 수정할 때는 엔티티를 조회해서 데이터만 변경하면 됌 (
em.update()
없음 )
- 변경감지: 엔티티의 변경사항을 데이터베이스에 자동으로 반영하는 기능
transaction.begin();
//영속 엔티티 조회
Member memberA = em.find(Member.class, "memberA");
memberA.setUsername("hi");
memberA.setAge(10);
//em.update(member); update 코드가 존재하지 않음
transaction.commit();
- 스냅샷: 엔티티를 영속성 컨텍스트에 보관할 때, 최초 상태를 복사해서 저장해두는 것을 의미
- 변경감지는 영속성 컨텍스트가 관리하는 영속 상태의 엔티티에만 적용
→ 비영속, 준영속은 반영 안됌
그림 실행 순서
- 트랜잭션을 커밋하면 엔티티 매니저 내부에서
플러시(flush())
호출
- 엔티티와 스냅샷을 비교 후 변경 엔티티 찾기
- 변경된 엔티티가 있으면 수정 쿼리 생성 후 쓰기 지연 SQL 저장소에 전달
- 쓰기 지연 SQL 저장소의 SQL을 데이터베이스 전달
- 데이터베이스 트랜잭션 커밋
- 엔티티의 변경된 부분만 수정하는 것이 아니라 엔티티의 모든 필드를 수정
<단점>
- 데이터베이스로 보내는 데이터 전송량이 증가하는 단점
<장점>- 수정 쿼리가 항상 동일, 애플리케이션 로딩 시점에 따라 미리 생성 및 재사용 가능
- 데이터베이스에 동일한 쿼리를 보내면 이전에 파싱된 쿼리를 재사용 가능
--예상되는 쿼리
UPDATE MEMBER
SET
NAME=?,
AGE=?
WHERE
id=?
--실제실행 쿼리
UPDATE MEMBER
SET
NAME=?,
AGE=?,
GRADE=?,
...
WHERE
id=?
- 수정한 데이터만 반영하고 싶은 경우, 동적 UPDATE SQL 생성하는 전략을 선택
- 하이버네이트 확장 기능 사용 (
@org.hibernate.annotations.DynamicUpdate
)
→ <참고> 확인이 필요 하지만 컬럼이 대략 30개 이상일때 정적보다 동적이 빠름
→ 테이블의 컬럼이 30개 이상인 경우 설계상 책임도 생각해보아야할 요소
@DynamicInsert
데이터가 존재하는 필드만으로 동적 INSERT SQL 생성
- 하이버네이트 확장 기능 사용 (
@Entity
@org.hibernate.annotations.DynamicUpdate
@Table(name = "member")
public class Member {...}
3.4.4 엔티티 삭제
- 삭제하려면 삭제 대상 엔티티 조회가 필요
Member memberA = em.find(Member.class, "memberA"); //삭제 대상 엔티티 조회
em.remove(memberA); //엔티티 삭제
- 엔티티를 즉시 삭제하는 것이 아니고 쓰기 지연 SQL 저장소에 등록
- 트랜잭션 커밋해서 플러시 호출하면 데이터베이스에 삭제 쿼리를 전달
em.remove(memberA)
를 호출하는 순간 memberA는 영속성 컨텍스트에서 제거
이미지 출처: https://ultrakain.gitbooks.io/jpa/content/chapter3/chapter3.4.html
'개발서적 > 자바 ORM 표준 JPA' 카테고리의 다른 글
[자바 ORM 표준 JPA 프로그래밍] 3.6 준영속 (0) | 2021.07.28 |
---|---|
[자바 ORM 표준 JPA 프로그래밍] 3.5 플러시 (0) | 2021.07.28 |
[자바 ORM 표준 JPA 프로그래밍] 3.3 엔티티의 생명주기 (0) | 2021.07.28 |
[자바 ORM 표준 JPA 프로그래밍] 3.2 영속성 컨텍스트란? (0) | 2021.07.28 |
[자바 ORM 표준 JPA 프로그래밍] 3.1 엔티티 매니저 팩토리와 엔티티 매니저 (0) | 2021.07.28 |