엔티티는 원래 영속상태로 관리됩니다. 값을 변경하면 트랜잭션 커밋 시점에 JPA가 플러시를 날려 변경된 내용을 확인하여 DB에 반영합니다.
준영속 엔티티
영속성 컨텍스트가 더는 관리하지 않는 엔티티를 말합니다.
@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";
}
여기서 itemService.saveItem(book) 에서 수정을 시도하는 Book 객체가 준영속 엔티티입니다. Book 객체는 이미 DB에 한번 저장되어서 식별자가 존재힙니다. 이렇게 임의로 만들어낸 엔티티도 기존 식별자를 가지고 있으면 준여옥 엔티티로 볼 수 있습니다.
준영속 엔티티는 JPA가 관리하지 않습니다. 즉, DB를 업데이트 하지 않습니다.
영속성 컨텍스트에서 엔티티를 다시 조회한 후에 데이터를 수정하는 방법.
트랜잭션 안에서 엔티티를 다시 조회, 변경할 값 선택 ➡️ 트랜잭션 커밋 시점에 변경 감지(Dirth Checking)이 동작해서 DB에 UPDATE SQL 실행.
@Transactional
void update(Item itemParam) { //itemParam: 파라미터로 넘어온 준영속 상태의 엔티티
Item findItem = em.find(Item.class, itemParam.getId()); //같은 엔티티를 조회한다.
findItem.setPrice(itemParam.getPrice()); //데이터를 수정한다.
}
병합은 준영속 상태의 엔티티를 영속 상태로 변경할 때 사용하는 기능입니다.
@Transactional
void update(Item itemParam) { //itemParam: 파라미터로 넘어온 준영속 상태의 엔티티
Item findItem = em.merge;
}

주의 : 변경 감지 기능을 사용하면 원하는 속성만 선택해서 변경할 수 있지만, 병합을 사용하면 모든 속성이 변경된다. 병합시 값이 없으면 null로 업데이트 할 위험도 있다. (병합은 모든 필드를 교체한다)
"엔티티를 변경할 때는 변경 감지를 사용하자."