DAY71(1) - 준영속 수정, CascadeType

은나현·2023년 5월 8일
0

📌 1. merge() vs 변경 감지

📍 1-1. 준영속과 비영속의 차이점

  • 영속상태가 되었던 경험 유무
    • 영속상태가 되기 위해서는 식별자가 필요하다. 따라서 준영속상태의 엔티티는 식별자가 존재한다는 것이 보장되지만 비영속 상태의 엔티티는 식별자가 존재할 수도, 존재하지 않을 수도 있다.
  • 준영속 엔티티를 수정하는 2가지 방법
    • 변경 감지 기능 사용
    • 병합(merge) 사용

📍 1-2. merge (병합) 동작 방식

  • em.merge() 실행
    • 파라미터로 넘어온 준영속 엔티티의 식별자 값으로 1차 캐시에서 엔티티 조회
    • 만약 1차 캐시에 엔티티가 없으면 데이터베이스에서 엔티티를 조회하고, 1차 캐시에 저장
  • merge는 1차 캐시에 있는 모든 내용을 수정한다.
    • 특정 값에 대한 수정을 원치 않아 코드상으로 막는 경우에는 그 값이 null로 처리되므로 수정 시 사용이 권장되지 않는다.

📍 1-3. 변경 감지 방식

  • 변경 감지 방식의 경우 영속성 컨텍스트 영역에서 save 또는 merge와 같은 메서드를 호출할 필요가 없다.
  • 영속성 컨텍스트에 변화가 일어나게 되면 JPA가 변화를 감지한다.
    • 따라서 Spring의 @Transactional에서 commit이 일어나게 되고 영속성 컨텍스트가 flush를 호출한다.
      • flush
        : 영속성 컨텍스트에서 변화가 생긴 부분을 감지 후 update 요청
  • 변경 감지에 의해서 데이터를 수정하는 방법
    // ItemRepository에 있는 조회 코드 ( 영속상태에 있으면 가져오고 없으면 DB 조회)
    	public Item findOne(Long itemId) {
    		return em.find(Item.class, itemId);
    	}
        ------------------------------------------------------------
    	@Transactional
    	public Item updateItem(Long id, ItemForm form) {
    		// id값을 기반으로 해서 실제 영속 상태의 데이터를 찾아온다
    		Item findItem = itemRepository.findOne(id);
    		findItem.setName(form.getName());
    		findItem.setPrice(form.getPrice());
    		findItem.setStockQuantity(form.getStockQuantity());
            // 별도의 메서드 호출 없이 데이터가 수정됨
    		return findItem;

➕ cascade = CascadeType.ALL

  • cascade : 영속성 전이
    • 특정 엔티티에 대해 특정한 작업을 수행하면 관련된 엔티티에도 동일한 작업을 수행한다는 의미이다.
    • 이 옵션은 부모 엔티티의 변경사항이 자식 엔티티에 모두 전파되도록 지정한다.
      • 부모 엔티티가 저장될 때 자식 엔티티도 함께 저장된다.
      • 부모 엔티티가 업데이트될 때 자식 엔티티도 함께 업데이트된다.
      • 부모 엔티티가 삭제될 때 자식 엔티티도 함께 삭제된다.
    • DB테이블상에서의 부모 테이블에 지정해야 한다.
      	@OneToMany(mappedBy = "order", cascade = CascadeType.ALL)
      	private List<OrderItem> orderItems = new ArrayList<>();

0개의 댓글