엔티티 구별
병합(merge)
병합(merge)이란?
우선 병합에 대해서 제대로 이해하고 있어야 한다.
병합(merge) 정리 포스팅에 정리해뒀다.
새로운 엔티티를 판단하기
기본 판단 전략
• 식별자가 객체일 때 null
로 판단
• 식별자가 자바 기본타입(primitive type)일 때 0
으로 판단
• Persistable 인터페이스를 구현해서 판단 로직 변경 가능
▷ Persistable Interface
public interface Persistable<ID> {
@Nullable
ID getId();
boolean isNew();
}
@GeneratedValue 있을 때
@GeneratedValue
어노테이션이 있을 때는 save()
메소드 호출시점에 식별자가
없기 때문에 새로운 엔티티로 인식해서 정상 작동한다.
@GeneratedValue 없을 때
@GeneratedValue
어노테이션이 없이 @Id
만 사용해서 직접 식별자를 할당하면,
Item item = new Item("id")
itemRepository.save(item);
이미 식별자가 있다고 판단하여 아래 이미지에 있는 em.merge()
를 호출한다.
merge는 우선 DB를 호출해서 값을 확인하고, DB에 값이 없으면 새로운 엔티티로
인지하므로 매우 비효율적이다.
직접 엔티티를 판단하기
Persistable 구현
@GeneratedValue
없을 때는 Persistable 인터페이스를 구현해서
새로운 엔티티 확인 여부를 직접 구현하게는 효과적이다.
@Entity
@EntityListeners(AuditingEntityListener.class)
@NoArgsConstructor(access = PROTECTED)
public class Item implements Persistable<String> {
@Id
private String id;
@CreatedDate
private LocalDateTime createdDate;
public Item(String id) {
this.id = id;
}
@Override
public String getId() {
return id;
}
@Override
public boolean isNew() {
return createdDate == null;
}
}
참고로 @CreatedDate
을 조합해서 사용하면 이 필드로 새로운 엔티티 여부를 편리하게
확인할 수 있다. @CreatedDate
에 값이 없으면 새로운 엔티티로 판단한다.