스프링 데이터 JPA 분석
구현체 분석
@Repository
@Transactional(readOnly = true)
public class SimpleJpaRepository<T, ID> ... {
@Transactional
public <S extend T> S save(S entity) {
if (entityInformation.isNew(entity)) {
em.persist(entity);
return entity;
} else {
return em.merge(entity);
}
}
}
@Repository
@Transactional(readOnly = true)
public class SimpleJpaRepository<T, ID> ... {
@Transactional
public <S extend T> S save(S entity) {
if (entityInformation.isNew(entity)) {
em.persist(entity);
return entity;
} else {
return em.merge(entity);
}
}
}
대충 스프링 데이터 JPA 구조는
전체적으로 @Transactional(readOnly = true)
를 이용해 읽기 전용으로 설정한 뒤에,
저장을하는 메서드가 나오면 메서드에 @Transactional
을 넣어 우선순위를 주는 구조로 짜여있음.
참고로 트랜잭션 옵션에 readOnly = true
설정을 하면 트랜잭션 끝날때 flush
를 생략하여 약간의 성능 향상을 얻을 수 있음
save()
메서드
- 새로운 엔티티면 저장(
persist
) - 새로운 엔티티가 아니면 병함(
merge
)
이전 강의 내용을 떠올려 보면,
머지를 사용할때 업데이트가 아니고 덮어씌우기이므로,
비어있는 부분을 다 새롭게 덮어버린다.
취약한 단점은 DB 설렉터를 호출하여 데이터를 가져온다는 점이다.
머지를 데이터 업데이트 용으로 사용하는 것은 좋지 않은 방법.
새로운 에티티를 구별하는 방법
새로운 엔티티를 판단하는 기준
- 식별자가 객체일 때
null
로 판단 - 식별자가 자바 기본 타입일때
0
으로 판단 Persistable
인터페이스를 구현해서 판단 로직 변경 가능
이 경우에 Item
객체에서 id
가 null
이면 새 엔티티,
값이 있으면 이미 있는 엔티티로 구분한다.
하지만, 이 아이디를 다른 형태로 값을 넣어서 받도록 구조를 짠다면,
비효율적인 로직이 발생되는데,
만약에 이상한 아이디 값을 넣어버린 상태로 save()
를 하게 되면,
null
이 아니므로 머지를 하게 된다.
그러면 select
문을 통해 DB에서 값을 찾게 되지만, 해당하는 아이디는 없으므로 그 후에 새롭게 저장하게 된다.
물론 평소에는 @GenerateValue
를 이용해
자동으로 할당해주는 방식을 많이 사용하기 때문에
상관없지만, 나중에는 @Id
만 이용해서 직접 할당으로 방식을 바꾼다던지,
임시로 값을 설정해야하는 상황이 있을때가 있다.
그럴때 위와 같은 상황을 피하고 좋은 로직을 만들기 위해서는
판단 기준을 내가 설정해야한다.
Persistable<String>
- 동작하려면
@EntityListeners(AuditingEntityListener.calss)
를 추가해야한다. isNew()
를 구현해야한다.- 구현하면, 새로운 엔티티 판단기준을 이 메서드로 잡게 된다.
그럼 이 부분에서 createdDate
를 판단 기준으로 바꾸기 때문에,
persist()
로 진행하는 것을 확인할 수 있다.
Author And Source
이 문제에 관하여(스프링 데이터 JPA 분석), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@seungju0000/스프링-데이터-JPA-분석저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)