[ JPA 객체 생명주기 ]
[ New - persist ]
New -> 비영속 객체 new User()처럼 새로 생성된 객체는 아직 영속성 컨텍스트(Persistence Context, PC)와 관련이 없고, 데이터베이스에 저장되지 않은 상태. (아직 PK가 없는 순수한 상태) 이 객체를 persist 메소드로 EntityManager한테 넘기면 (영속성 컨텍스트. PC한테 넘겼다고 생각해도 된다) 객체는 영속성 컨텍스트 내부에 존재하게 된다. 그러나 즉시 데이터베이스에 저장되는 것은 아니기 때문에 영속화 된 건 아니다! (실제 데이터베이스에 반영되기 전까지는 메모리 내에서만 관리 됨) id(PK)가 있냐 없냐만 딱 체크해서 Managed가 insert 쿼리같은 걸 DB에 flush 날린다. (new한 객체를 보고 쿼리문을 생성함) 이제 아까 new된 비영속 객체가 동기화가 되어서 영속 객체로 바뀌는 것.
[ Remove ] → 우린 remove 사용하지 않는다
remove를 하면 PC에서 빠져나올 거잖아? PC에서 빠져나온다고 해서 실제로 삭제된 게 아니다. 통신(flush)를 안했으니까... 객체를 뺐으니까 DELTE쿼리에 대한 버퍼가 딱 담기면서 트랜젝션 종료 시 FLUSH를 하라고 대기 타는 중 정리하자면, 영속 상태의 객체에 remove 메소드를 사용하면, 해당 객체는 삭제 상태가 된다. 삭제 상태의 객체는 트랜잭션이 커밋되는 시점에 DELETE 쿼리를 통해 데이터베이스에서 삭제된다.
[ merge ]
merge 같은 경우는 업데이트 할 때 사용한다. (분리 상태의 객체를 다시 영속 상태로 만들고 싶을 때는 merge 메소드를 사용) 영속화된 애를. .detach 같은걸 해서 pc에서 밖으로 꺼낸다. 밖으로 꺼냈으니 비영속화된 상태. 이 상태로, 상태를 변경하고 나서 merge요청을 하면 업데이트가 된다! -> 우린 이걸로 안할거다 ㅎㅎ
우린 영속화 되어있는 애의 상태만 변경 시키면 자기가 더티 체킹으로 알아서 업데이트 flush를 날릴 것.
[ Detach ]
Detach는 영속성 컨텍스트(Persistence Context, PC) 내의 특정 엔티티를 분리(detach)하는 작업 이 작업을 통해 해당 엔티티는 더 이상 영속 상태가 아닌 비영속(detached) 상태가 된다. 비영속 상태의 엔티티는 영속성 컨텍스트의 관리를 받지 않으므로, 변경 감지(dirty checking)나 지연 로딩과 같은 JPA의 기능을 사용할 수 없다.
[ Clear ] ✓
영속성 컨텍스트를 완전히 초기화하는 작업. 이 작업을 수행하면, 영속성 컨텍스트 내의 모든 엔티티가 비영속 상태가 된다. 즉, clear를 사용하면 영속성 컨텍스트 내의 모든 엔티티가 관리 대상에서 제외 됨.
[ flush ] ✓
영속성 컨텍스트의 변경 내용을 데이터베이스에 반영한다. 보통 트랜잭션이 커밋되는 시점에 자동으로 호출되지만, 필요에 따라 수동으로 호출할 수도 있다. -> 주로 단위 테스트 시에 데이터베이스와의 동기화를 확인하기 위해 수동으로 사용
단위 테스트 시에는 flush가 없어서 (트랜젝션 종료가 되려면 (컨트롤러가 호출하는 거니까) 컨트롤러까지 가야 하는데 단위 테스트는 레파지토리부터 시작하기 때문에 쿼리문이 날아가지 않는다) 쿼리가 전송되진 않고 그냥 꺼내기만 함. 그래서 수동으로 flush를 적어준다. (쿼리문 날아가는지 확인하기 위해서)
TIP!
요청이 컨트롤러를 거쳐 서비스 레이어로 이동하고, 최종적으로 리포지토리(Repository) 레이어에서 데이터베이스와의 상호작용이 일어난다. 이 과정에서 트랜잭션이 시작되고, 서비스 레이어에서의 비즈니스 로직 처리가 끝나면 트랜잭션이 종료(commit 혹은 rollback)됨. 트랜잭션이 종료되는 시점에 JPA는 flush를 자동으로 호출하여 영속성 컨텍스트의 변경 내용을 데이터베이스에 반영한다.
clear 정도는 기억하자! -> 단위 테스트에서 필요. 캐싱되서 select 쿼리가 안 날아가니까... 쿼리문 확인 위해서 쿼리가 날아가는지 테스트하기 위해선 필요 그러나!! clear를 실제 로직에서 쓸 일은 절대 없다. 캐싱되는게 훨씬!! 좋기 때문이다!! flush도 어짜피 트랜젝션이 종료되면 알아서 날아가기 때문에 쓸 일 없다. 그러나 테스트에선 clear, flush 둘 다 필요!
영속화 된 애를 꺼냈다고 쿼리가 날아가는게 아니다!
트랜젝션이 종료되는 시점, DB와 연결되는 시점에야… 쿼리가 날아가는 것!
Share article