매우중요※변경 감지와 병합(merge)※

2023. 5. 18. 09:46카테고리 없음

참고: 정말중요한 내용이니꼭! 완벽하게 이해하자

준영속엔티티?

영속성컨텍스트가 더는관리하지않는엔티티를말한다.
(여기서는 itemService.saveItem(book) 에서수정을 시도하는 Book 객체다. Book 객체는 이미 DB
에한번 저장되어서 식별자가존재한다. 이렇게임의로 만들어낸엔티티도 기존식별자를가지고 있으면
준영속엔티티로 볼수있다.)

  • 데이터베이스 한번 들어갔다 온 상태(식별자가 정확하게 있는 상태)를 준영속 컨텍스트 라고함.

준영속엔티티를 수정하는 2가지방법

  • 변경감지기능사용
  • 병합( merge ) 사용

변경 감지 기능 사용

@Transactional
void update(Item itemParam) { //itemParam: 파리미터로 넘어온 준영속 상태의 엔티티 
    Item findItem = em.find(Item.class, itemParam.getId()); //같은 엔티티를 조회한다.
    findItem.setPrice(itemParam.getPrice()); //데이터를 수정한다. 
}
  • 영속성컨텍스트에서 엔티티를 다시 조회한후에데이터를 수정하는방법
    트랜잭션 안에서 엔티티를 다시 조회, 변경할값 선택 트랜잭션 커밋시점에 변경 감지(Dirty Checking)(이)가 동작해서 데이터베이스에 UPDATE SQL 실행

병합 사용
병합은준영속 상태의 엔티티를영속상태로 변경할때사용하는 기능이다.

@Transactional
void update(Item itemParam) { //itemParam: 파리미터로 넘어온 준영속 상태의 엔티티 
    Item mergeItem = em.merge(itemParam);
}

merge : 파라미터로 넘어온 값과 찾아온 값을 바꿔치기 해버림.  그니까 내가 트랜젝션으로 만든 여러개의 코드를 머지 하나로 해줌.

 

관계

병합동작방식(이렇게보면 진짜 모르겠다) (질문)
1.   merge() 를실행한다.
2.  파라미터로넘어온 준영속엔티티의 식별자값으로 1차캐시에서 엔티티를조회한다.
2-1. 만약 1차 캐시에엔티티가없으면 데이터베이스에서 엔티티를조회하고, 1차캐시에 저장한다.
3.  조회한영속 엔티티( mergeMember )에 member 엔티티의값을 채워넣는다. (member 엔티티의 모든 
값을 mergeMember에밀어넣는다. 이때 mergeMember의 “회원1”이라는이름이 “회원명변경”으로 
바뀐다.)
4.  영속상태인 mergeMember를 반환한다.

 

기존의 파라미터로 넘어온 값은 영속성 컨텍스트로 변하진 않는다.

머지로 받은 변수가 영속성 컨텍스트에서 관리되는 애임.

 

병합시동작 방식을 간단히정리
1.  준영속엔티티의 식별자값으로 영속엔티티를조회한다.
2.  영속엔티티의값을 준영속엔티티의값으로 모두교체한다.(병합한다.)
3.  트랜잭션 커밋시점에 변경감지기능이동작해서데이터베이스에 UPDATE SQL이 실행

 

※주의※: 변경감지기능을 사용하면 원하는 속성만 선택해서 변경할수 있지만, 병합을 사용하면 모든속성이 
변경된다. 병합 시값이 없으면 null 로 업데이트 할 위험도 있다. (병합은 모든필드를 교체한다.)

ex) 그니까 책 가격이 만원이었는데, 그냥 한번 저장시켜놓고 안바꾼다고 가격 빼버리고 머지시키면 책 가격이 데이터베이스에 들어갈때 null로 들어감.(그럼 0원인가? 공짜?)

 

그래서 코드를 만들때 추적할수있게끔 의미있는 코드를 사용하는게 중요함.(setName이런거 말고 .change() 등)

 

가장 좋은해결 방법


엔티티를 변경할때는 항상 변경 감지를 사용하자

 

 

출처 : 인프런 강의: 실전! 스프링 부트와 JPA 활용1 - 웹 애플리케이션 개발

https://www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81%EB%B6%80%ED%8A%B8-JPA-%ED%99%9C%EC%9A%A9-1/dashboard

 

실전! 스프링 부트와 JPA 활용1 - 웹 애플리케이션 개발 - 인프런 | 강의

실무에 가까운 예제로, 스프링 부트와 JPA를 활용해서 웹 애플리케이션을 설계하고 개발합니다. 이 과정을 통해 스프링 부트와 JPA를 실무에서 어떻게 활용해야 하는지 이해할 수 있습니다., - 강

www.inflearn.com