새로운 Entity인지 판단
3줄요약
- JpaEntityInformation의
isNew(T entity)
에 의해 판단된다. - 추가적인 설정이 없다면 JpaEntityInformation의 구현체 중 JpaMetamodelEntityInformation 클래스가 동작하게 된다.
@Version
이 사용된 필드가 없거나@Version
이 사용된 필드가 primitive 타입이면 AbstracEntityInformation의isNew()
를 호출한다.
본문
일반적으로 JpaEntityInformation의은 JpaMetamodelEntityInformation가 사용이 되는데
해당 JpaMetamodelEntityInformation안에서 isNew(T entity)
를 사용되며
@Override
public boolean isNew(T entity) {
if (versionAttribute.isEmpty()
|| versionAttribute.map(Attribute::getJavaType).map(Class::isPrimitive).orElse(false)) {
return super.isNew(entity);
}
BeanWrapper wrapper = new DirectFieldAccessFallbackBeanWrapper(entity);
return versionAttribute.map(it -> wrapper.getPropertyValue(it.getName()) == null).orElse(true);
}
내부의 super.isNew(entity)
를 열어보게 되면
@Override
public boolean isNew(T entity) {
ID id = getId(entity);
Class<ID> idType = getIdType();
if (!idType.isPrimitive()) {
return id == null;
}
if (id instanceof Number n) {
return n.longValue() == 0L;
}
throw new IllegalArgumentException(String.format("Unsupported primitive id type %s", idType));
}
라는 코드를 확인할수 있게 되는데 id의 타입이 primitive 타입이 아닌 경우에는 null인 경우만 새로운 엔티티로 판단하게 된다.
하지만 primitive 타입 중 해당 타입의 Wrapper 클래스가 Number의 하위 타입인 경우(int, long 등)에는 해당 값이 0인 경우에만 이를 새로운 엔티티라 판단한다.
새로운 entity를 판단하는 기준이 중요한 이유는
@Override
@Transactional
public <S extends T> S save(S entity) {
Assert.notNull(entity, ENTITY_MUST_NOT_BE_NULL);
if (entityInformation.isNew(entity)) {
entityManager.persist(entity);
return entity;
} else {
return entityManager.merge(entity);
}
}
SimpleJpaRepository
의 save 메서드를 보면 알수가 있다.save()
메서드에서 isNew()
를 사용하여 persist를 수행할지 merge를 수행할지 결정하게된다.
만약 ID를 직접 지정해주는 경우에는 신규 entity라고 판단하지 않기 때문에 merge를 수행하게되고, 이때 entity는 신규데이터 임에도 불구하고 DB를 조회하기 때문에 비효율적인 연산이 늘어나게 된다.
'지식저장소' 카테고리의 다른 글
JPA의 N + 1 (0) | 2025.04.01 |
---|---|
엔티티 매니저에 대하여 (0) | 2025.03.28 |
카프카 알아보기 (0) | 2025.02.17 |
정적 팩토리 메서드란? (0) | 2024.11.19 |
OAuth 2.0 이란 무엇일까.2 (0) | 2022.03.25 |