728x90
반응형
스프링 데이터 JPA 구현체 분석
스프링 데이터 JPA가 제공하는 공통 인터페이스의 구현체
(org.springframework.data.jpa.repository.support.SimpleJpaRepository
)
@Repository
@Transactional(readOnly = true)
public class SimpleJpaRepository<T, ID> ...{
@Transactional
public <S extends T> S save(S entity) {
if (entityInformation.isNew(entity)) {
em.persist(entity);
return entity;
} else {
return em.merge(entity);
}
}
...
}
@Repository
적용
(1) 스프링 빈의 컴포넌트 스캔 대상
(2) JPA나 JDBC 예외를 스프링이 추상화한 예외로 변환된다. 결과적으로 하부 구현 기술을 바꿔도 기존 비즈니스 로직에 최대한 영향을 주지 않도록 잘 설계되어 있다.@Transactional
적용
(1) JPA의 모든 변경은 트랜잭션 안에서 동작
(2) 스프링 데이터 JPA는 변경(등록, 수정, 삭제) 메소드를 트랜잭션 처리
(3) 서비스 계층에서 트랜잭션을 시작하지 않으면 레포지토리에서 트랜잭션 시작
(4) 서비스 계층에서 트랜잭션을 시작하면 레포지토리는 해당 트랜잭션을 전파 받아 사용@Transactional(reaadOnly = true)
데이터를 단순히 조회만 하고 변경하지 않는 트랜잭션에서readOnly = true
옵션을 사용하면 플러시를 생략하기 때문에 약간의 성능 향상을 얻을 수 있다.- save()
새로운 엔티티일 경우 저장(persist), 새로운 엔티티가 아니면 병합(merge)으로 동작하며 병합의 단점으로는 SELECT 쿼리가 무조건 실행된다. 데이터 업데이트 시 병합은 절대 사용하지 말고 변경감지를 이용하여 사용하는 것을 권장하며 병합은 어떠한 이유로 영속상태가 풀렸을 경우 다시 영속상태로 만들기 위해 사용한다.
새로운 엔티티를 구별하는 방법
새로운 엔티티 판단 전략
- 식별자가 객체일 때 NULL로 판단
- 식별자가 자바 기본 타입일 때 0으로 판단
- Persistable 인터페이스를 구현하여
isNew()
오버라이딩
package org.springframework.data.domain; public interface Persistable<ID> { ID getId(); boolean isNew(); }
Persistable 구현
@Entity
@EntityListeners(AuditingEntityListener.class)
@NoArgsConstructor(access = AccessLevel.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;
}
}
@GenerateValue
는EntityManager.persist()
가 호출되어야 값이 생성된다.@Id
어노테이션만 사용하여 식별자를 구성할 경우 기존isNew()
함수에서는 식별자의 유무로persist()
와merge()
호출을 구분한다. 따라서 Persistable 인터페이스를 상속받아isNew()
함수를 오버라이딩하여 식별자 유무가 아닌 다른 로직으로persist()
와merge()
를 구분하여야 한다.
※ 참고로 등록시간(@CreatedDate
)을 조합해서 사용하면 이 값으로persist()
와merge()
를 구분하기 편리하다.
728x90
반응형
'Dev > Spring Data JPA' 카테고리의 다른 글
[Spring Data JPA] 나머지 기능들 (0) | 2021.12.19 |
---|---|
[Spring Data JPA] 확장 기능 (0) | 2021.12.13 |
[Spring Data JPA] 쿼리 메소드 기능 (0) | 2021.12.09 |
[Spring Data JPA] 공통 인터페이스 기능 (0) | 2021.11.29 |
[Spring Data JPA] 예제 도메인 모델 (0) | 2021.11.29 |
댓글