[Spring] Repository // JPA

soohee·2023년 2월 10일
0

Spring

목록 보기
5/13

JPA 사용이유

  1. sql을 다루지않고, business logic에서 data만 바꾸면, jpa가 알아서 바뀐 변경 포인트들을 dirty checking(변경된 감지)가 일어나서, database에 업데이트 쿼리를 촥촥 넣어준다.

준영속 entity

영속성 컨텍스트가 더이상 관리하지 않은 entity.
= 제대로 database에 갔다온 객체, jpa가 식별할 수 있는 id를 가지고 있다.

준영속 entity를 수정하는 2가지 방법

▫️ 변경 감지 기능 사용 (Dirty chekcing)

파라미터로 넘어온 준영속 상태의 엔티티로 같은 엔티티를 조회해서 값을 set해주면 자동으로 spring의 @Transactional에 의해서 commit이 된다.
그럼 jpa는 flush(영속성 컨텍스트 중에서 변경된 애들이 어떤 것들이 있는지 확인)를 수행해서 db에 save한다.

▫️ 병합 사용 (Merge)

준영속 상태의 엔티티를 영속 상태로 변경할 때 사용하는 기능.

  1. merge()를 시행한다.
  2. 파라미터로 넘어온 준영속 엔티티의 식별자 값으로 1차 캐시에서 엔티티를 조회한다.
  3. 조회한 영속 엔티티(a')에 해당 엔티티 값(a)을 채워넣는다.
    a의 모든 값을 a'에 밀어넣는다.
  4. 영속 상태인 a'을 반환한다.

따라서, Item aItem = em.merge(item); 에서,
item의 값은 변경되지 않고, aItem이 영속성 컨텍스트가 관리하는 객체가 된다.

🛑주의🛑 변경 감지 기능을 사용하면 원하는 속성만 선택해서 변경할 수 잇지만, 병합을 사용하면 모든 속성이 변경된다.
따라서, 병합시 값이 없으면 null로 업데이트 할 위험도 있다.(병합은 모든 필드를 교체)

이렇게 사용하세요

  • 컨트롤러에서 어설프게 엔티티 생성X
  • 트랜잭션 있는 서비스 계층에 식별자와 변경할 데이터를 확실히 전달해라(parameter or dto)
  • 트랜잭션 있는 서비스 계층에서 영속 상태의 엔티티를 조회하고, 엔티티의 데이터를 직접 변경해라.

그렇게 한다면 트랜잭션 커밋 시점에 변경 감지가 실행된다.

QueryDsl

profile
🐻‍❄️

0개의 댓글