일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
Tags
- springbootproxy
- JPA값타입
- jpa
- 스프링부트
- springbootH2
- spring
- 스프링부트기본설정
- dockercmd
- JDBC connection pool
- JPAproxy
- JPAmapping
- javageneric
- gitinitial
- Git
- embededtype
- OSIV
- JPA프록시
- Open EntityManager
- MySqlType
- 에이치투데이터베이스
- JPA Hint & Lock
- sql
- 임베디드타입
- 자바제너릭
- httppie
- springboot기본설정
- 제이피큐엘쿼리
- 데이터베이트h2
- jpqlquery
- 이해와 원리
Archives
- Today
- Total
빡코
[스프링데이터JPA] 새로운 엔티티(Entity)를 구별하는 방법 본문
새로운 엔티티를 판단하는 기본전략
-식별자가 객체일 때 null로 판단 > 새로운 것으로 판단
-식별자가 자바 기본타입일 때 0으로 판단
ex) private long id ; 자바의 기본형이기 때문에 객체가 아니고, Null을 넣을 수 없기 때문에 0으로 판다
- Persistable인터페이스를 구현해서 판단로직 변경가능(실무에서 사용)
id 값이 자동생성이 아닌 특별한 경우에 의하여 직접 채번이 된다고 가정해보자 .
@Entity
@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class Item {
@Id
private String id;
public Item(String id) {
this.id = id;
}
}
@SpringBootTest
class ItemRepositoryTest {
@Autowired ItemRepository itemRepository;
@Test
public void save() {
Item item = new Item("A");
itemRepository.save(item);
}
}
Persistable인터페이스
Item 엔티티에 Persitable 인터페이스 구현
package study.datajpa.entity;
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import org.hibernate.hql.spi.id.persistent.PersistentTableBulkIdStrategy;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.domain.Persistable;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;
import javax.persistence.*;
import java.time.LocalDateTime;
@Entity
@EntityListeners(AuditingEntityListener.class)
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class Item implements Persistable<String> {
@Id
private String id;
@CreatedDate //jpa persist가 되기전 호출이 됨
private LocalDateTime createdDate;
public Item(String id) {
this.id = id;
}
@Override
public String getId() {
return id;
}
@Override
public boolean isNew() {
//여기서 어떤 조건이면 새것인지 아닌지 로직을 직접 짜야한다.
return createdDate == null; //-> 새로운 객체로 인정하고 진행
}
}
> JPA persist가 되기전 createdDate 값체크
> null 체크로 신규 또는 이미 존재하는 Id인지 확인
신규인 경우 persist, 기존인 경우 Merge 진행
public class SimpleJpaRepository<T, ID> implements JpaRepositoryImplementation<T, ID> {
public <S extends T> S save(S entity) {
if (entityInformation.isNew(entity)) { // -> 여기에 걸림
em.persist(entity);
return entity;
} else {
return em.merge(entity);
}
}
}
참고:
JPA 식별자생성전략이@GenerateValue면 save() 호출시점에 식별자가 없으므로 새로운 엔티티로 인식해서 정상동작한다. 그런데 JPA 식별자생성전략이@Id만 사용해서 직접 당이면 이미 식별자값이 있는 상태로 save()를호출한다.
따라서 이 경우 merge()가 호출된다. merge()는 우선 DB를 호출해서 값을 확인하고, DB에 값이 없으면 새로운 엔티티로 인지하므로 매우 비효율적이다. 따라서 Persistable를 사용해서 새로운 엔티티확인여부를 직접 구현하게는 효과적이다.> 참고로 등록시간(@CreatedDate)을조합해서 사용하면이 필드로 새로운 엔티티여부를 편리하게 확인할 수 있다. (@CreatedDate에 값이 없으면 새로운 엔티티로 판단)
'Java > JPA' 카테고리의 다른 글
[JPA] 스프링데이터 JPA (0) | 2023.12.27 |
---|---|
[querydsl] 스프링부트 3.0 + java 17 build.gradle 설정 파일 (0) | 2023.05.31 |
[스프링데이터JPA] 스프링테이터 JPA 분석 (0) | 2023.05.12 |
[스프링데이터 JPA] Web 확장 - 도메인클래스컨버터, 페이징과 정렬 (0) | 2023.05.12 |
[스프링데이터 JPA] Auditing (0) | 2023.05.11 |