@PostMapping("/items/{itemId}/edit")
public String updateItem(@PathVariable("itemId") String itemId, @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";
}
@Transactional
public void updateItem(Long itemId, Book param){//param: 파라미터로 넘어온 준영속 상태의 엔티티
Item findItem = itemRepository.findOne(itemId);
findItem.setPrice(param.getPrice());
findItem.setName(param.getName());
findItem.setStockQuantity(param.getStockQuantity());
}
@Transactional
void update(Item itemParam) { //itemParam: 파라미터로 넘어온 준영속 상태의 엔티티
Item mergeItem = em.merge(item);
}
주의!!! 변경감지 기능을 사용하면 원하는 속성만 변경할 수 있지만, 병합을 사용하면 모든 속성이 변견됨. 병합시 값이 없으면 null로 변경 될 위험 있음.(실무에서는 가급적으로 merge사용하지 않음)
@Controller
@RequiredArgsConstructor
public class ItemController {
private final ItemService itemService;
/**
* 상품 수정, 권장 코드
*/
@PostMapping(value = "/items/{itemId}/edit")
public String updateItem(@ModelAttribute("form") BookForm form) {
itemService.updateItem(form.getId(), form.getName(), form.getPrice());
return "redirect:/items";
}
}
package jpabook.jpashop.service;
@Service
@RequiredArgsConstructor
public class ItemService {
private final ItemRepository itemRepository;
/**
* 영속성 컨텍스트가 자동 변경
*/
@Transactional
public void updateItem(Long id, String name, int price) {
Item item = itemRepository.findOne(id); // id가 있으면 transactional 안에서 entity를 조회해야 영속성 컨테스트가 됨. 거기에 값을 변경해야 dirty checking 가능.
item.setName(name);
item.setPrice(price);
}
}
@Repository
public class ItemRepository {
@PersistenceContext
EntityManager em;
public void save(Item item) {
if (item.getId() == null) {
em.persist(item);
} else {
em.merge(item);
}
}
@Transactional
public void updateItem(Long itemId, Book param){
Item findItem = itemRepository.findOne(itemId);
// 이렇게 의미있는 method 만들기
findItem.change(price,name,stockQuantity);
findItem.addStock(10);
// setter 사용 지양
findItem.setPrice(param.getPrice());
findItem.setName(param.getName());
findItem.setStockQuantity(param.getStockQuantity());
return findItem;
}