본문 바로가기

Development/Diary

[개발 일기] 이게 왜 null이 아니야 (영속성 컨텍스트에서 같은 Entity를 참조!)

테스트 코드 공부 중에 의아한 점.

Product givenProduct = Product.builder()
                .name("note")
                .price(1000)
                .stock(500)
                .build();

        System.out.println("before save = " + givenProduct.getNumber());

        // when
        Product savedProduct = productRepository.save(givenProduct);

        // then
        System.out.println("after save = " + givenProduct.getNumber());

위 출력 결과는 다음과 같다.

before save = null
Hibernate: 
    insert 
    into
        product
        (created_at, name, price, provider_id, stock, updated_at, number) 
    values
        (?, ?, ?, ?, ?, ?, default)
after save = 1

그런데 after save에는 왜 null이 아닐까?

저장된 savedProduct는 Id 값을 할당받으니 savedProduct에만 Id 값이 있어야 하는거 아닌가?

그런데 givenProduct의 number를 출력해봤더니 null이 아닌 1이 출력되는 것이다.

이유

productRepository.save(givenProduct)를 호출하면 다음 순서로 진행된다.

  1. JPA 또는 Hibernate는 영속성 컨텍스트에 이미 존재하는 엔티티인가? 없으면 올려놓는다.
  2. 그리고 save()를 통해 데이터베이스로부터 새로 저장된 엔티티를 받아서 영속성 컨텍스트에 이미 같은 엔티티가 존재하면 merge 한다.
  3. givenProduct와 savedProduct는 같은 엔티티이기 때문에, 결과적으로 같은 메모리의 객체를 참조하게 된다.
  4. 그래서 givenProduct에도 Id 값이 반영되는 것.

디버그 모드로 확인해 본 모습.