데이터의 수정이 일어났을 때, 업데이트된 정보를 DB에 반영하는 두 가지 방법이 있다.
@PostMapping("items/{itemId}/edit")
public String updateItem(@PathVariable String itemId, @ModelAttribute("form") BookForm form) {
Book book = new Book();
book.setId(form.getId());
itemService.saveItem(book);
return "redirect:/items";
}
// public void saveItem(Item item) {
// if (item.getId() == null) {
// em.persist(item); // 신규 등록
// } else {
// em.merge(item); // 병합
// }
// }
변경되어 넘어온 BookForm을 새로운 Book 객체에 Setter를 통해 변수들을 설정하면 자동으로 업데이트 되지 않는다.
그 이유는 book은 단지 내가 만들었을 뿐 영속성 객체가 아니기 때문이다.
이를 업데이트할 수 있는 방법이 바로 merge이다.
merge는 내가 이해한 바로는 영속성 컨텍스트에 등록되어 있는 영속성 엔티티와 내가 생성한 book을 병합시켜주는 것이다.
그러나, 값이 설정되지 않은 것들도 병합되기 때문에 null값이 들어갈 수 있어 실무에서는 절대 사용하면 안 된다.
@Transactional
void update(Item itemParam) { //itemParam: 파리미터로 넘어온 준영속 상태의 엔티티
Item findItem = em.find(Item.class, itemParam.getId()); //같은 엔티티를 조회한다.
findItem.setPrice(itemParam.getPrice()); //데이터를 수정한다.
}
그렇다면 위의 코드에 findItem도 merge 해줘야 할까?
그럴 필요가 없다. 왜냐하면 em.find로 찾은 엔티티는 영속성 엔티티이기 때문!
자동으로 반영된다.