테스트를 잘 통과하고 서버에도 프론트에도 잘나오는 이아이는 테스트 할때 마다 골치다
아니 대체 왜 저장한 것을 반환하는 값이 항상 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
'개발 관련 학습 및 문제해결' 카테고리의 다른 글
리액트에서 CK에디터 구현하기 1.[20221105 TIL] (0) | 2022.11.05 |
---|---|
자바 스프링 부트 컨트롤러 406 Not Acceptable 에러[20221104-TIL] (0) | 2022.11.04 |
ManyToOne, OneToMany 를 쓰지않고 DTO에 List 속성 넣어주기[20221102 TIL] (0) | 2022.11.02 |
자바 DTO의 속성값에 배열넣어주기[20221101-TIL] (0) | 2022.11.01 |
데이터베이스에 배열 넣기?[20221031-TIL] (0) | 2022.10.31 |
댓글