본문 바로가기
개발 관련 학습 및 문제해결

Jpa repository save 는 왜 null 일까? 1[20221103 TIL]

by 날파리1 2022. 11. 3.

테스트를 잘 통과하고 서버에도 프론트에도 잘나오는 이아이는 테스트 할때 마다 골치다

아니 대체 왜 저장한 것을 반환하는 값이 항상 null 인가?

그래서 일단은 verify 로 이게 호출되었는지만 테스트를 하고 있긴 하다.

 

JPA 기본 구현체에 구현되어있는 save() 구현

@Transactional
@Override
public <S extends T> S save(S entity) {

    Assert.notNull(entity, "Entity must not be null.");

    if (entityInformation.isNew(entity)) { // (1)
        em.persist(entity);
        return entity;
    } else {
        return em.merge(entity);
    }
}

(1) isNew()의 반환 타입에 따라 저장할지 병합할지 결정한다.

isNew() 메서드는 새로운 Entity를 판단하기 위해 ID값을 확인하는 원리

  • ID의 타입이 객체 타입(reference)일 때: null
  • ID의 타입이 기본 타입(primitive)일 때: 0
  • Persistable 인터페이스를 구현한 경우: 구현체 내에서 override
package org.springframework.data.domain;

import org.springframework.lang.Nullable;

public interface Persistable<ID> {

    @Nullable
    ID getId();

    boolean isNew();
}

Persistable 인터페이스는 두 가지 메서드를 가지는데 ID를 반환하는 메서드와 새로운 객체 여부를 판단하는 isNew() 메서드 입니다.

save()에서 호출했던 isNew()가 바로 이 메서드입니다.

따라서 isNew()를 Entity의 속성들을 이용해 원하는 방식으로 구현할 경우, 해당 로직에 의해 새로운 Entity 유무를 판단합니다.

다시 위의 테스트로 돌아가서 Item Entity에 @GeneratedValue 애너테이션이 추가되어있기 때문에 Entity에 ID 값을 따로 설정해주지 않아도 save() 시점에 isNew() 메서드를 통해 새로운 Entity로 판단한 뒤 생성 전략에 따라 알아서 ID 값을 생성해 저장해주게 됩니다.

 

 

일단 save 메서드가 발현되는 조건이 여러가지 있다는 걸 알겠고 그중 첫째가 isNew 라는 건데... 아직은 잘 어렵다. 위글은 그나마 초입부를 잘 정리해놓은 블로그를 가져 온 것인데 일단 isNew() 이면 persist를 호출하고 아니면 merge를 해서 생성유무를 결정하는데..

 

  • entity 가 새로 생성할 예정이라면 persist() 를 호출하고, 그렇지 않다면 merge() 를 호출합니다.

 

아직은 이게 왜 save 의 반환값을 테스트코드나 실제코드에서 null 인지 모르겠다 내일 추가학습을 해보도록하자!

 

 

참고 블로그

https://jaime-note.tistory.com/65

 

스프링 데이터 JPA - 새로운 Entity 판별

) 모든 소스 코드는 여기에서 확인할 수 있습니다. 바로 이전 포스팅에서 JPA가 save()를 호출할 때 새로운 Entity인지 기존 Entity인지 판단해 persist() 또는 merge()를 호출한다는 내용을 다룬 바 있습니

jaime-note.tistory.com

 

댓글