JPA - Dirty Checking (변경감지)

Kim Dae Hyun·2021년 7월 22일
0

JPA

목록 보기
2/4
post-thumbnail

🔎 Dirty Checking

JPA가 제공하는 객체와 DB를 매핑시키는 ORM 기술 중 하나로 객체와 DB의 관계를 자바 컬렉션과 컬렉션의 아이템 관계처럼 다루는 것이 가능합니다.

아래 코드를 통해 자바 컬렉션과 해당 컬렉션의 아이템 관계를 생각해볼께요.

public class test {
    public static void main(String[] args) {
        List<Member> list = new ArrayList<>();
        list.add(new Member(1L, "kim"));
        list.add(new Member(2L, "lee"));

        Member member = list.get(0);
        member.setName("수정된 이름");

        System.out.println(list.get(0).getName());
    }

    @AllArgsConstructor
    @Getter @Setter
    static class Member{
        private Long id;
        private String name;
    }
}

list의 첫번째 아이템을 가져와서 name을 수정하고 출력해보았습니다. 결과는 아래와 같습니다.

우리는 수정된 member를 다시 컬렉션에 넣어주지 않았습니다.
하지만 값은 의도한 대로 잘 변경되었지요.
이런 컬렉션과 컬렉션의 아이템 관계를 DB와 객체의 관계로 그대로 가져와 볼께요.

컬렉션은 DB가 될 것이고 컬렉션의 아이템은 DB에 저장될 객체가 됩니다.


🔎 JPA를 이용한 예시

컬렉션이 DB가 되는 것이니 아래와 같이 DB를 구성하였습니다.

아래 코드는 find 메서드를 통해 ID가 1인 Member를 가져와서 가져온 Member의 name을 변경하는 코드입니다.

try{
    Member member = em.find(Member.class, 1L);
    member.setName("수정된 이름");

    tx.commit();
} catch(Exception e) {
    tx.rollback();
} finally {
    em.close();
}

조회 후에 값을 바꾸고 다시 DB에 persist(영속화)를 해주어야 할까요?

컬렉션과 마찬가지로 다시 영속화해주지 않아도 됩니다.
여기서 영속화는 컬렉션에 다시 add하는 것과 같은 것 입니다.

쿼리의 내용도 select 이후 update로 아주 정상적으로 나갔고 DB에도 잘 반영되었습니다.


🔎 간단한 내부 동작 소개

영속성 컨텍스트 내에는 1차 캐시가 있습니다.
처음 find 메서드를 이용해 Member를 조회한 시점에 DB에서 해당하는 Member를 찾아 영속성 컨텍스트의 1차 캐시에 넣어줍니다.

이때 1차 캐시의 Member 값이 하나의 스냅샷이 되는 것 입니다.

이후 Member의 이름을 변경하고 commit 시점에 수정된 Member와 1차 캐시의 스냅샷 Member와 비교하여 update query를 만드는 것 입니다.

profile
좀 더 천천히 까먹기 위해 기록합니다. 🧐

0개의 댓글