데이터베이스에 한번 다녀온,, 즉 식별자가 데이터베이스 안에 있는 경우(ex. 이미 만들어진 게시글 db를 수정할때, 해당 db는 준영속 엔티티)
jpa가 식별할 수 있는 Id가 있기 때문에 영속성 컨텍스트가 더이상 관리하지 않음.
@PostMapping("items/{itemId}/edit")
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";
}
jpa가 더이상 관리하지 않음.
따라서 아무리 값 변경을 시켜도 jpa가 db를 update 해주지 않음
@Transactional
public void updateItem(Long itemId, Book param){
Item findItem = itemRepository.findOne(itemId);
findItem.setPrice(param.getPrice());
.... (대충 findItem 에 값을 다 세팅했다고 치고)
// 여기까지만 하면 jpa가 flush를 날려서 변경 완료.
}
이때 em.merge(item)에서 item은 영속상태로 변하지 않기 때문에
만약 변경된 데이터를 쓰고 싶다면
Item m = em.merge(item) 으로 처리 후, m 을 사용해야함.
public void save(Item item){
if(item.getId() == null) {
em.persist(item);
} else{
em.merge(item); // similar with update
}
}
🎈결론 : 가급적이면 병합을 쓰기보다는 변경 감지를 쓰자!