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에 저장될 객체가 됩니다.
컬렉션이 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
를 만드는 것 입니다.