
🔗 코드 확인하기

view 리소스 등록🔗 부트스트랩
resources/static 하위에 css, js 추가resources/static/css/jumbotron-narrow.css 추가jumbotron-narrow.css는 강사님 코드)🔗 코드 확인하기


→ 회원 가입에 성공하면 홈 화면으로 리다이렉트된다.


MemberForm.java@NotEmpty(message = "회원 이름은 필수 입니다")
private String name;
→ 이렇게 @NotEmpty 어노테이션이 달려있는 필드는 필수값으로 설정한다.


📌 폼 객체 vs 엔티티 직접 사용
실무에서 엔티티는 핵심 비즈니스 로직만 가지고 있고, 화면을 위한 로직은 없어야 한다.
화면이나 API에 맞는 폼 객체나 DTO를 사용해서 화면이나 API 요구사항을 처리하고, 엔티티는 최대한 순수하게 유지하자!
/items/new를 POST 방식으로 요청redirect:items)으로 리다이렉트


/items/{itemId}/edit URL을 GET 방식으로 요청한다.updateItemForm() 메서드를 실행한다.itemService.findOne(itemId)를 호출해서 수정할 상품을 조회한다.items/updateItemForm)에 전달한다.Submit 버튼을 클릭한다./items/{itemId}/edit URL을 POST 방식으로 요청하고 updateItem() 메서드를 실행한다.item 엔티티 인스턴스는 현재 준영속 상태!

수정 완료!
merge) ] ⭐💡 준영속 엔티티
: 영속성 컨텍스트가 더는 관리하지 않는 엔티티
@PostMapping("/items/{itemId}/edit")
public String updateItem(@ModelAttribute("form") BookForm form, @PathVariable String itemId){
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에 한 번 저장되어서 식별자가 존재한다.📌 준영속 엔티티를 수정하는 2가지 방법
- 변경 감지 기능 사용
- 병합(
merge) 사용
영속성 컨텍스트에서 엔티티를 다시 조회한 후에 데이터를 수정하는 방법
@Transactional
public void updateItem(Long itemId, Book param) {
Item findItem = itemRepository.findOne(itemId);
findItem.setPrice(param.getPrice());
findItem.setName(param.getName());
findItem.setStockQuantity(param.getStockQuantity());
}
트랜잭션 안에서 준영속 엔티티인 param을 인자로 받아서 조회하고, 변경할 값을 선택한다.
→ 트랜잭션 커밋 시점에 변경 감지(Dirty Checking)가 동작해서 데이터베이스에서
UPDATE SQL 실행
이렇게 변경을 감지해서 업데이트하는 것을 변경 감지라고 한다.
준영속 상태의 엔티티를 영속 상태로 변경할 때 사용하는 기능
@Transactional
void update(Item itemParam) {
Item mergeItem = em.merge(item);
}

merge()를 실행한다.mergeMember)에 member 엔티티의 값을 채워 넣는다. member 엔티티의 모든 값을 mergeMember에 밀어 넣는다.mergeMember의 회원1 → 회원명변경)mergeMember를 반환한다.📌 병합시 동작 방식 정리
- 준영속 엔티티의 식별자 값으로 영속 엔티티를 조회한다.
- 영속 엔티티의 값을 준영속 엔티티의 값으로 모두 교체한다. (병합한다.)
- 트랜잭션 커밋 시점에 변경 감지 기능이 동작해서 데이터베이스에
UPDATE SQL이 실행된다.
🚫 주의!
- 변경 감지 기능은 원하는 속성만 선택해서 변경할 수 있지만,
병합은 모든 속성이 변경된다.- 병합은 모든 필드를 교체하기 때문에 값이 없으면
null로 업데이트 할 위험도 있다.
결론 ❗ 엔티티를 변경할 때는 항상 변경 감지를 사용하자!
- 컨트롤러에서 어설프게 엔티티를 생성하지 말자.
- 트랜잭션이 있는 서비스 계층에 식별자(
id)와 변경할 데이터를 명확하게 전달하자. (파라미터 ordto)- 트랜잭션이 있는 서비스 계층에서 영속 상태의 엔티티를 조회하고, 엔티티의 데이터를 직접 변경하자.
- 트랜잭션 커밋 시점에 변경 감지가 실행된다.
🔗 코드 확인하기
🔗 코드 확인하기
/order를 GET 방식으로 호출한다.OrderController의 createForm() 메서드를 호출하고,model 객체에 주문한 고객 정보와 상품 정보를 담아서 뷰에 넘겨준다.Submit 버튼을 누르면 /order를 POST 방식으로 호출한다.OrderController의 order() 메서드를 호출하고,memberId), 주문할 상품 식별자(itemId), 수량(count) 정보를 받아서 주문 서비스에 주문을 요청한다./orders로 리다이렉트한다.

🔗 코드 확인하기

