DevKim

[JPA] 엔티티의 생명주기 & 플러시 (flush) 본문

JPA

[JPA] 엔티티의 생명주기 & 플러시 (flush)

on_doing 2021. 5. 20. 18:13
728x90

[ 엔티티의 생명주기 ]

1. 비영속 (new/transient)

- 비영속은 말 그대로, 영속성 컨텍스트와 전혀 관계가 없는 새로운 상태이다.

= 그냥 객체만 생성했을 때 - JPA와 관계 X


2. 영속 (managed)

- 영속 상태가 되어 관리되어지는 상태를 이야기한다.

em.persist( )


3. 준영속 (detached)

- 영속 상태였던 애를 , 영속성 컨텍스트에서 분리한 상태

=> 분리한 후에 commit을 해도 update 쿼리가 나가지 않는다.

em.detach( )

 

****************************** 참고 ********************************

준영속 상태로 만드는 방법은 직접 쓸 일은 없고 원리만 이해하면 된다!

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

em.detach(entity)

 

2> 영속성 컨텍스트를 완전히 초기화 ( 1차 캐시도 통으로 지움)

em.clear( )

 

3> 영속성 컨텍스트를 종료

em.close( ) 

***********************************************************************

 

4. 삭제 (removed)

- 객체를 삭제한 상태이다.

=실제 DB에서 지우겠다는 것

em.remove( )

 


[ 플러시 flush ]

한줄로 이야기하자면

' 영속성 컨텍스트의 변경 내용을 데이터베이스에 반영' 하는 것이다.

DB commit이 발생하면 자동으로 플러시가 발생한다.

 

플러시가 발생하면

1. dirty checking

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

3. 저장소의 쿼리를 DB에 전송

 

머릿속에 그림으로 막 그려지면 이해해 성공한 것이다!


영속성 컨텍스트를 플러시하는 방법

- 직접 쓰는 일은 별로 없지만 알아는 둬야한다고 한다.

 

1. em.flush( )로 직접 호출

2. 트랜잭션 commit ( 플러시 자동 호출 )

3. JPQL 쿼리 실행 ( 자동 호출 )

-> data가 DB에 반영되기 전인데, JPQL 쿼리에서 객체의 뭐든 것을 가져오려고한다면 

오류가 날 것이다. 이를 방지해서 JPA가 자동으로 그냥 같이 호출한다고한다.

 

******************* 헷갈리지 말아야 할 것 ******************

- 플러시가 발생한다고해서, 영속성 컨텍스트를 비우는 것이 아니다!!

( 1차 캐시가 지워지는 것이 아니다!!)

 

- 영속성 컨텍스트의 변경내용을 DB에 동기화하는 것이다.

***************************************************************

 

어차피 트랜잭션 작업 단위가 중요하므로, 커밋 직전에만 동기화되면 되는데

실제로 이런거에 대한 문제가 발생하지는 않는다고 한다.

 

* 설계할 땐, 영속성 컨텍스트와 트랜잭션의 주기를 맞춰서 설계가 들어가야 문제가 없다 *

 

 

그림 출처 : 자바 ORM 표준 JPA 프로그래밍

728x90
Comments