김영환님의 강의 실전! 스프링 부트와 JPA 활용1 - 웹 애플리케이션 개발 보면서 공부한 내용입니다.
📝 준영속 엔티티
준영속 엔티티
로 볼 수 있다💡 준영속 엔티티의 문제점
- 영속성 컨텍스트에서 관리하지 않기 때문에 set~를 통해 값을 변경해도 DB에서 update가 이루어지지 않는다.
📝 준영속 엔티티 수정 방법
✅ 변경 감지 기능 사용
/*
1. 변경 감지 기능 사용
*/
@Transactional
public void updateItem(Long itemId, Book bookParam){
// Book bookParam : 파라미터로 넘어온 준영속 상태의 엔티티
Item findItem = itemrepository.find(itemId); // 영속 상태 => 같은 엔티티를 조회
findItem.setName(bookParam.getName());
//값이 새롭게 세팅됐기때문에 commit이 됨 => flush를 날려서 변경 감지 => db에서 update 실행
findItem.setPrice(bookParam.getPrice());
findItem.setStockQuantity(bookParam.getStockQuantity());
}
영속성 컨텍스트에서 엔티티를 다시 조회한 후에 데이터를 수정하는 방법
: 트랜잭션 안에서 엔티티를 다시 조회, 변경할 값 선택 → 트랜잭션 커밋 시점에 변경 감지(Dirty Checking)이 동작 → 데이터베이스에 update sql실행
✅ 병합(merge) 사용
/*
2. 병합(merge) 사용
*/
@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); // 변경된 item값을 넘김
return "redirect:/items";
}
// 상품 저장
public void save(Item item){
if(item.getId() == null){
em.persist(item);
} else {
Item merge = em.merge(item); // 이미 db에 등록된 것을 가져온 것이므로 update 개념으로 생각하면됨 => '`merge' 영속성 컨텍스트에서 관리하는 엔티티
}
}
//=========================================================
// 아래 코드와 동일한 동작방식
@Transactional
public Item updateItem(Long itemId, Book bookParam){
Item findItem = itemrepository.find(itemId); // 영속 상태
findItem.setName(bookParam.getName()); // 값을 새로 세팅됐기때문에 commit이 됨 => flush를 날려서 변경 감지 => db에서 update 실행
findItem.setPrice(bookParam.getPrice());
findItem.setStockQuantity(bookParam.getStockQuantity());
return findItem;
}
준영속 상태의 엔티티를 영속 상태로 변경할 때 사용하는 기능
merge()
를 실행한다.mergeMember
)에 member 엔티티의 값을 채워 넣는다. (member 엔티티의 모든 값을 mergeMember에 밀어 넣는다. 이때 mergeMember의 “회원1”이라는 이름이 “회원명변경”으로 바뀐다.)💡 주의!
- 변경 감지를 사용하면 원하는 속성만 선택해서 변경할 수 있지만, 병합을 사용하면 모든 속성이 변경된다. 병합시 값이 없으면
null
로 업데이트 할 위험도 있다. (병합은 모든 필드를 교체한다.)