JPA

영속성 관리 - 내부 동작 방식

tmxhsk99 2022. 7. 26. 11:38

해당 글은 김영한님 인프런 강의(

)를 듣고 정리한글이다.

 

JPA에서 가장 중요한 2가지

• 객체와 관계형 데이터베이스 매핑하기

(Object Relational Mapping)

• 영속성 컨텍스트

 

 

 

 

영속성 컨텍스트

• JPA를 이해하는데 가장 중요한 용어

• “엔티티를 영구 저장하는 환경”이라는 뜻

• EntityManager.persist(entity);

 

 

영속화한다

Persist db 저장하는게 아닌 영속성 컨텍스트에 저장한다.

 

엔티티 매니저?

영속성 컨텍스트?

• 영속성 컨텍스트는 논리적인 개념

• 눈에 보이지 않는다.

• 엔티티 매니저를 통해서 영속성 컨텍스트에 접근

 

 

엔티티의 생명주기

• 비영속 (new/transient)

영속성 컨텍스트와 전혀 관계가 없는 새로운 상태

• 영속 (managed)

영속성 컨텍스트에 관리되는 상태

• 준영속 (detached)

영속성 컨텍스트에 저장되었다가 분리된 상태

• 삭제 (removed)

삭제된 상태

 

 

그냥 객체만 셋팅하므로 비영속 상태

 

 

DB 코드사이의 하나의 계층이 있는

 

영속성 컨텍스트의 이점

• 1차 캐시

• 동일성(identity) 보장

• 트랜잭션을 지원하는 쓰기 지연

(transactional write-behind)

• 변경 감지(Dirty Checking)

• 지연 로딩(Lazy Loading)

 

 

 

얘기냐

1차로 persist 호출시 등록한 객체는 1 캐시에 저장되고

trasaction.commit DB 등록 된다.

등록 되기전 바로 해당 객체를 찾으면 DB 쿼리를 날리지 않고 1 캐시에

있는 값을 가져온다.

그리고 commit 등록만 이루어짐

 

EntityManager 초기화되면 해당 값도 초기화된다.

 

 

조회도 1 조회하면 해당 값을 DB에서 조회해서 영속성 컨텍스트에 올려놓는다.

그후 다시 해당 값을 조회하게 되면 1 캐시에서 값을 가져와 DB와는 통신하지 않는다.

 

 

 

 

 

하이버네이트 배치 설정으로 모았다 하는 개수를 정할 수도 있다

 

 

커밋하면

 entity  스냅샷을 비교

스냅샷 : 최초 읽어온 시점의

비교해서 업데이트 쿼리를 날림

 

플러시

영속성 컨텍스트의 변경내용을

데이터베이스에 반영

 

 

플러시 발생

• 변경 감지

• 수정된 엔티티 쓰기 지연 SQL 저장소에 등록

• 쓰기 지연 SQL 저장소의 쿼리를 데이터베이스에 전송

(등록, 수정, 삭제 쿼리)

 

 

영속성 컨텍스트를

플러시하는 방법

• em.flush() - 직접 호출

• 트랜잭션 커밋 - 플러시 자동 호출

• JPQL 쿼리 실행 - 플러시 자동 호출

 

 

JPQL 쿼리 실행시 플러시가 자동으로 호출되는 이유

em.persist(memberA);
em.persist(memberB);
em.persist(memberC);
//중간에 JPQL 실행
query = em.createQuery("select m from Member m", Member.class);
List<Member> members= query.getResultList();

 

persist 단계는 쿼리가 실행이 안됨

근데 jPQL 다시 Member 호출하려고 하니까

쿼리는 반영이 안됬으므로 데이터가 안맞아버림

그러므로 JPQL 실행시에는 flush() 호출되고

JPQL 실행된다.

 

 

플러시 모드 옵션

em.setFlushMode(FlushModeType.COMMIT)

• FlushModeType.AUTO

커밋이나 쿼리를 실행할 때 플러시 (기본값)

• FlushModeType.COMMIT

커밋할 때만 플러시

 

 

플러시는!

• 영속성 컨텍스트를 비우지 않음

• 영속성 컨텍스트의 변경내용을 데이터베이스에 동기화

• 트랜잭션이라는 작업 단위가 중요 -> 커밋 직전에만 동기화

하면 됨

 

 

준영속 상태

• 영속 -> 준영속

• 영속 상태의 엔티티가 영속성 컨텍스트에서 분리(detached)

• 영속성 컨텍스트가 제공하는 기능을 사용 못함

 

 

준영속 상태로 만드는 방법

• em.detach(entity)

특정 엔티티만 준영속 상태로 전환

• em.clear()

영속성 컨텍스트를 완전히 초기화

• em.close()

영속성 컨텍스트를 종료