본문 바로가기
JPA

JPA 를 공부하면서 알게 된 내용 정리 4

by 성건희 2022. 2. 5.
반응형

Spring Data JPA - 3편

JpaRepository 분석하기

JpaRepository 를 까보면 구현체로 SimpleJpaRepository 를 사용한다.

  • @Repository 를 적용해서 JPA 예외를 스프링이 추상화 한 예외로 변환한다.
  • @Transactional 트랜잭션 적용
    • JPA 의 모든 동작은 트랜잭션 안에서 동작
    • 스프링 데이터 JPA 는 변경 (등록, 수정, 삭제) 메서드를 트랜잭션 처리
    • 서비스 계층에서 트랜잭션을 시작하지 않으면 리파지토리에서 트랜잭션 시작
    • 서비스 계층에서 트랜잭션을 시작하면 리파지토리는 해당 트랜잭션을 전파 받아서 사용
    • 그래서 스프링 데이터 JPA 를 사용할 때 트랜잭션이 없어도 데이터 등록, 변경이 가능했던 것이다.
      (사실은 트랜잭션이 리포지토리 계층에 걸려있는 것임)

save() 메서드

해당 내용은 중요하기 때문에 꼭 이해해두기!

  • 새로운 엔티티면 저장 (persist)
  • 새로운 엔티티가 아니면 병합 (merge)

entityInformation.isNew() 로 새로운 엔티티를 판단하는 기본 전략

  • 식별자가 객체일 때 null로 판단 - ex) Long 타입
  • 식별자가 자바 기본 타입일 때 0 으로 판단
  • Persistable인터페이스를 구현해서 판단 로직 변경 가능

위 내용을 잘 모르면 실무에서 이슈가 발생할 수 있다.
예를들어 아래와 같이 Item 엔티티를 만들어 둔다. (이때 @Id 는 @GeneratedValue 가 아님)

Item 엔티티를 save 할 때 문제가 발생한다.


PK 값이 넘어오기 때문에 isNew 메서드에서 false 가 발생하여 em.merge 를 해버리게 된다.

em.merge 는 실제 DB 에 값이 있다고 가정하기 때문에 select 쿼리를 날린다.
하지만 실제로는 값이 없으므로 insert 를 날려준다.

결과적으로 insert 는 되지만 불필요한 select 쿼리가 나가므로 비효율적이다.

PK 자동 생성(@GeneratedValue) 을 어쩔 수 없이 못쓰는 상황은 어떻하나요?

보통 대부분의 경우 자동 생성으로 엔티티를 생성하지만, 정말 어쩔 수 없이 못쓰는 상황이 있을 수 있다.
이때는 Persistable 을 사용해서 새로운 엔티티 확인 여부를 직접 구현하면 된다.


Persistable<식별자 타입> 을 implements 해주고
getId(), isNew() 를 구현해주면 된다.

보통 실무에서는 위와 같이 등록 시간 (@CreatedDate ) 을 조합해서 사용한다.
(@CreatedDate 에 값이 없으면 새로운 엔티티로 판단)

참고 : @CreatedDate 는 @EntityListeners 가 있어야 한다.
persist 가 되면 @CreatedDate 로 데이터가 들어간다.

Tip ) command + F12 단축키를 통해 해당 클래스 내 메서드를 쉽게 조회할 수 있다.

@Transactional(readOnly = true)

데이터를 단순히 조회만 하고 변경하지 않는 트랜잭션에서 해당 옵션을 사용하면 플러시를 생략해서 약간의 성능 향상을 얻을 수 있다.

복잡한 통계성 쿼리는..

동적 쿼리를 편리하게 작성하기 위해 QueryDSL을 사용한다.
하지만 QueryDSL 도 결국은 JPQL 기반이라, 지원하지 않는 쿼리는
Spring JDBC Template 이나 Mybatis 등을 이용하여 쿼리를 짠다.

from절 서브 쿼리 - 인프런 | 질문 & 답변

참고

  • 실전! 스프링 데이터 JPA
반응형

'JPA' 카테고리의 다른 글

Querydsl - 2편  (0) 2022.02.08
Querydsl - 1편  (0) 2022.02.08
JPA 를 공부하면서 알게 된 내용 정리 3  (0) 2022.02.02
JPA 를 공부하면서 알게 된 내용 정리 2  (0) 2022.01.29
JPA 를 공부하면서 알게 된 내용 정리 1  (0) 2022.01.26

댓글