반응형
스프링 데이터 JPA 분석
- 스프링 데이터 JPA가 제공하는 공통 인터페이스의 구현체
- org.springframework.data.jpa.repository.support.SimpleRepository
SimpleJpaRepository
구현 분석
@Repository 적용
- JPA 예외를 스프링이 추상화 한 예외로 반환
- JPA가 아닌 다른 시스템의 예외도 동일한 형태로 추상화를 함
- 시스템에 종속적이지 않은 코드 구성 가능
@Transactional트랜잭션 적용
- JPA의 모든 변경은 트랜잭션 안에서 동작
- 서비스 계층에서 트랜잭션 시작 X: 리파지토리에서 트랜잭션 시작
- 서비스 계층에서 트랜잭션 시작 O: 해당 트랜잭션을 이어받아 사용
- SimpleJpaRepository에 구현된 메소드들이 이미 트랜잭션 안에서 처리되도록 구성됐기 때문에 사용 시 트랜잭션 없이 데이터 등록, 변경 가능
@Transactional(readOnly = true)
- 트랜잭션을 생성하는 매커니즘은 옵션이 없는 상태와 같음
- 단지 옵션을 사용하면 트랜잭션 마지막에 flush()를 생략
- 약간의 성능 향상
save() 메소드
엔티티를 저장할 때
- 새로운 엔티티: persist()
- 새로운 엔티티 X: merge()
새로운 엔티티 판별법
- 식별자(ID)가 객체: null인지 여부로 판단
- 식별자(ID)가 기본 타입: 0인지 여부로 판단
save()실행 순서
- save()호출 시 isNew()메소드를 이용해 엔티티의 ID가 null 또는 0인지 확인
- 1번이 yespersist(), nomerge()
문제점
만약 ID값을 직접 넣은 후 save()호출한다면?
ID가 null 또는 0이 아니기 때문에 merge() 호출
select쿼리 이후 없다고 판단한 뒤 insert쿼리
매우 비효율적
해결 방법
Persistable인터페이스를 구현해 isNew()메소드를 재정의
Persistable 인터페이스
등록 시간(@CreatedDate)을 이용하면 새로운 엔티티 여부를 쉽게 확인 가능
- @CreatedDate에 값이 없으면 새로운 엔티티
Persistable 구현 예시
@Entity
@EntityListeners(AuditingEntityListener.class)
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class Item implements Persistable<Long> {
@Id
private Long id;
@CreatedDate
private LocalDateTime createdDate;
public Item(Long id) {
this.id = id;
}
@Override
public Long getId() {
return id;
}
@Override
public boolean isNew() {
return createdDate == null;
}
}
"본 포스트는 작성자가 공부한 내용을 바탕으로 작성한 글입니다.
잘못된 내용이 있을 시 언제든 댓글로 피드백 부탁드리겠습니다.
항상 정확한 내용을 포스팅하도록 노력하겠습니다."
반응형
'Spring' 카테고리의 다른 글
안전한 Lombok 사용법 (0) | 2023.02.06 |
---|---|
equals(), hashcode() (0) | 2023.02.06 |
Spring data JPA: 확장 기능 (0) | 2023.02.06 |
Spring data JPA: 쿼리 메소드 (3) (0) | 2023.02.06 |
Spring data JPA: 쿼리 메소드 (2) (0) | 2023.02.06 |