빙응의 공부 블로그
[Spring]실전! 스프링 부트와 JPA 활용1 - 변경 감지와 병합 본문
📝변경 감지와 병합(merge)
JPA에서 값을 업데이트는 어떻게 하는걸까?
변경 감지!!
🚩변경감지
- JPA에서 엔티티를 조회한 후, 해당 엔티티의 상태를 추적하여 변경 여부를 감지하는 매커니즘을 말한다.
- 엔티티의 상태가 변경되는 JPA는 트랜잭션 커밋 시점에서 변경을 감지해 업데이트 쿼리를 날려준다.
- 이는 영속성 컨텍스트에서 관리되기에 적용되는 범위이다.!!
@Transactional
void update(Item itemParam) { //itemParam: 파리미터로 넘어온 준영속 상태의 엔티티
Item findItem = em.find(Item.class, itemParam.getId()); //같은 엔티티를 조회한다.
findItem.setPrice(itemParam.getPrice()); //데이터를 수정한다.
}
위처럼 따로 사용자가 업데이트 쿼리를 안날려도 트랜잭션 커밋 시점에서 데이터를 감지, 수정한다.
그렇다면 병합은 무엇일까?
병합이란 쉽게 말해서 준영속 상태를 영속 상태로 변경하는 것이다.
준영속 상태
영속성 컨텍스트가 더는 관리하지 않는 엔티티를 말한다.
public String updateItem(@ModelAttribute("form") BookForm form) {
Book book = new Book();
book.setId(form.getId());
book.setName(form.getName());
book.setPrice(form.getPrice());
book.setStockQuantity(form.getStockQuantity());
book.setAuthor(form.getAuthor());
book.setIsbn(form.getIsbn());
itemService.saveItem(book);
return "redirect:/items";
}
위의 코드를 보자, 해당 구문의 Book은 새로 만들어 영속 상태가 아니지만, DB의 저장되는 식별자를 가지고 있어 준영속 상태로 볼 수 있다.
🚩준영속 엔티티를 수정하는 방법
준영속 상태를 수정하는 방법은 2가지가 있다.
- 변경 감지 기능 사용
- 병합 사용
변경 감지 기능
따로 Item 객체를 찾아 넘어온 파라미터로 업데이트를 하는 방법이다. 쉽게 말해 지금까지 해온 방법이다.
@Transactional
void update(Item itemParam) { //itemParam: 파리미터로 넘어온 준영속 상태의 엔티티
Item findItem = em.find(Item.class, itemParam.getId()); //같은 엔티티를 조회한다.
findItem.setPrice(itemParam.getPrice()); //데이터를 수정한다.
}
병합 사용
@PostMapping("/items/{itemId}/edit")
public String updateItem(@PathVariable("itemId") Long itemId, BookForm form) {
Book book = new Book();
book.setId(form.getId());
book.setName(form.getName());
book.setPrice(form.getPrice());
book.setStockQuantity(form.getStockQuantity());
book.setAuthor(form.getAuthor());
book.setIsbn(form.getIsbn());
if(book.getId() != null) { //Book의 ID가 null이 아니면
Item item = em.merge(book); //영속화
}
}
병합은 준영속 상태의 엔티티를 영속 상태로 변경할 대 사용하는 기능이다.
병합 동작 방식
- merge()를 실행한다.
- 파라미터로 넘어온 준영속 엔티티의 식별자 값으로 1차 캐시에서 엔티티를 조회한다.
- 만약 엔티티가 없으면 데이터베이스에서 엔티티를 조회하고, 1차 캐시에 저장한다.
- 저장한 엔티티를 들어온 파라미터로 업데이트한다.
병합의 주의점
병합 시 들어온 파라미터의 값으로 모두 변경하기 때문에 병합시 값이 없으면 null로 업데이트하는 위험이 있다.
결론:
가급적이면 변경 감지를 사용하자!
'Spring > 인프런_JPA' 카테고리의 다른 글
[Spring] 컬렉션 조회 최적화 (0) | 2024.07.04 |
---|---|
[Spring]JPA 지연 로딩 성능 최적화 (0) | 2024.07.03 |
[Spring]자바 ORM 표준 JPA 프로그래밍 - 객체지향 쿼리 언어2 (0) | 2024.02.25 |
[Spring]자바 ORM 표준 JPA 프로그래밍 - 객체지향 쿼리 언어 (0) | 2024.02.23 |
[Spring]자바 ORM 표준 JPA 프로그래밍 - 값 타입 (1) | 2024.02.22 |