본문 바로가기
Back-End/Spring Data

8.변경감지 와 병합

by 두두리안 2021. 1. 1.
728x90

8.변경감지 와 병합

  • 1.준영속 엔티티

1.준영속 엔티티

  • 영속성 컨텍스트가 더이상 관리하지 않는 엔티티 (준영속 상태 객체도 있다)
  • 수정을 시도한 Book 엔티티 객체는 이미 DB에 한번 저장되어서 식별자가 존재

준영속 엔티티 를 수정하는 방법

  • 1.변경감지는 트랜잭션안에서 값이 바뀌면 자동으로 Update 해준다 (더티체킹) 그리나서 커밋해준다
  • 2.Merge 사용하기

1.변경감지 ItemService

@Service
@Transactional(readOnly = true)
@RequiredArgsConstructor
public class ItemService {

    private final ItemRepository itemRepository;

    @Transactional
        public void updateItem(Long itemId, String name, int price, int stockQuantity){
            Item findItem = itemRepository.findOne(itemId);
            findItem.setName(name);
            findItem.setPrice(price);
            findItem.setStockQuantity(stockQuantity);
        }
}
  • itemRepository 에서 가져온 itemId 객체를 findItem 반환하면 영속성 컨텍스트에서 관리하는 객체가 들어온다
  • findItem.setPrice 을 트랜잭션 안에서 해주면 JPA 가 알아서 변경을 감지해서 Update 해준다

2.병합(Merge)

@Repository
@RequiredArgsConstructor
public class ItemRepository {

    private final EntityManager em;

    //상품 생성
    public void save(Item item){
        if(item.getId()==null){
            em.persist(item);
        }else{
            em.merge(item);
        }
    }
}
  • merge 는 준영속 엔티티를 영속상태로 변경할때 사용
  • 위에 변경감지와 비슷하게 동작한다
  • Merge 는 모든 데이터를 바꿔 치운다 그리고나서 반환한다
  • 그러나 넘어온 객체는 영속성으로 바뀌지 않는다

주의!

  • 병합시 값이 없으면 Null 로 업데이트 할수있다
  • 변경 감지는 변경된 부분만 업데이트 해준다
  • 엔티티를 변경할때는 항상 변경감지를 사용하자

컨트롤러에서 엔티티를 생성하지 말자 (ItemController)

@Controller
@RequiredArgsConstructor
public class ItemController {

    private final ItemService itemService;


    /**
     * 상품 수정
     */
    @PostMapping(value = "/items/{itemId}/edit")
    public String updateItem(@PathVariable("itemId") Long 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);*/

        itemService.updateItem(itemId,form.getName(),form.getPrice(),form.getStockQuantity());

        return "redirect:/items";
    }


}
  • 기존 컨트롤러에서 Book 엔티티를 생성했지만 updateItem 만들어서 엔티티 생성을 지운다
  • 트랜잭션이 있는 서비스 계층에 식별자 id 와 변경할 데이터를 명확하게 전달(파라미터 or DTO)
  • 트랜잭션 서비스 계층에서 영속상태의 엔티티를 조회하고 엔티티의 데이터를 직접 변경
  • 정리 : 트랜잭션 영속성 엔티티 사용 -> 변경감지 -> 변경된부분만 수정

참고자료

https://www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81%EB%B6%80%ED%8A%B8-JPA-%ED%99%9C%EC%9A%A9-1/dashboard (웹 애플리케이션개발)

728x90

'Back-End > Spring Data' 카테고리의 다른 글

1.JPA 소개  (0) 2021.01.04
9.웹 계층 개발 2(주문)  (0) 2021.01.01
7.웹 계층 개발 1(회원,상품)  (0) 2021.01.01
6.주문도메인개발  (0) 2020.12.30
5.상품도메인 개발  (0) 2020.12.30