개발놀이터

스프링 dirty checking과 merge 본문

Spring/Spring

스프링 dirty checking과 merge

마늘냄새폴폴 2021. 8. 31. 02:02

*변경감지(Dirty Checking)와 병합(merge)


준영속 엔티티란?
영속성 컨텍스트가 더는 관리하지 않는 엔티티를 말한다. em.persist로 넣을 때 혹은 em.find 등으로 디비에서 값을 가져올 때 영속성 컨텍스트에 데이터들이 들어간다. 임의로 만든 엔티티가 식별자를 가지고 있으면 준영속 엔티티로 간주한다. 

준영속 엔티티를 수정하는 2가지 방법
1. 변경감지(Dirty Checking)
2. 병합(merge)

1. 변경감지
영속성 컨텍스트에서 엔티티를 다시 조회한 후에 데이터를 수정하는 방법이다. 트랜잭션 안에서 엔티티르 다시 조회, 변경할 값 선택 -> 트랜잭션 커밋 시점에 변경 감지가 작동해 데이터베이스에 update 쿼리가 날아간다.

2. 병합
병합의 동작 방식
1. merge()를 실행한다.
2. 파라미터로 넘어온 준영속 엔티티의 식별자 값으로 1차 캐시에서 엔티티를 조회한다. (만약 1차캐시에 엔티티가 없으면 데이터베이스에서 엔티티를 조회하고 1차캐시에 저장한다.)
3. 조회한 영속 엔티티에 새로운 값을 엔티티에 채워넣는다. 
4. 영속 상태인 엔티티를 반환한다.

병합의 동작 방식은 3번 조회한 영속 엔티티에 새로운 값을 엔티티에 채워 넣을 때 모든 값을 다 바꿔서 채워 넣는다. 예를 들어서 나는 이름필드만 바꾸고 싶어서 이름만 setName으로 바꿔버리면 나머지 필드들은 전부 null로 업데이트 쿼리가 날아간다. 때문에 병합을 사용할 때에는 모든 필드를 다 변경해 줘야 한다.


*병합의 실무 설계
병합은 실무에서 사용하지 않는 것이 좋다. 왜냐하면 보통 어떤 필드를 변경할 때 필드가 10개라면 네다섯개정도 변경하는 것이 일반적인데 값을 변경할 때마다 모든 필드의 값을 전부 다 세팅해 줘야 하는 것은 유지보수측면에서 그리고 실용적인 측면에서 옳지못한 방식이 될 수 있다. 예를 들어서 실무에는 모든 테이블에 누가 수정했는지 언제 수정했는지 등의 필수적으로 들어가는 필드가 있기 마련이다. 이렇게 필수적으로 들어가있는 필드 마저도 값을 세팅해주지 않으면 null로 값이 업데이트 되기 때문에 내가 변경하고자 하는 필드만 따로 메서드로 빼서 변경하는 것이 올바른 선택이다. 

'Spring > Spring' 카테고리의 다른 글

타임리프기본2  (0) 2021.10.15
타임리프기본1  (0) 2021.10.13
스프링 RedirectAttribute  (0) 2021.08.21
타임리프  (0) 2021.08.19
스프링 MVC 기본기능 핵심정리  (0) 2021.08.19