엔티티 수정
SQL을 사용하면 수정 쿼리를 직접 작성해야 한다.
그렇게 하면 수정 쿼리가 많아지는 것은 물론이고 비즈니스 로직을 분석하기 위해 SQL을 계속 확인해야 한다.
결국 직접적이든 간접적이든 비즈니스 로직이 SQL에 의존하게 된다.
JPA로 엔티티를 수정할 때는 단순히 엔티티를 조회해서 데이터만 변경하면 된다.
즉, 엔티티의 변경사항을 데이터베이스에 자동으로 반영하는 기능 : 변경 감지(dirty checking)
package jpabook.start;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
@Entity
@Table(name="MEMBER")
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class Member {
@Id
@Column(name = "ID")
private String id;
@Column(name = "NAME")
@Getter
private String username;
@Getter
private int age;
public void update(String username, int age) {
this.username = username;
this.age = age;
}
}
package jpabook.start;
import javax.persistence.*;
import java.util.List;
public class JpaMain {
public static void main(String[] args) {
// 엔티티 매니저 팩토리 - 생성
EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory("jpabook");
// 엔티티 매니저 - 생성
EntityManager entityManager = entityManagerFactory.createEntityManager();
// 트랜잭션 - 획득
EntityTransaction entityTransaction = entityManager.getTransaction();
try {
// 트랜잭션 - 시작
entityTransaction.begin();
// 비즈니스 로직 - 실행
update(entityManager);
//여기까지 insert SQL 을 데이터베이스에 보내지 않는다.
// 트랜잭션 - 커밋
entityTransaction.commit();
} catch (Exception e) {
// 트랜잭션 - 롤백
entityTransaction.rollback();
} finally {
// 엔티티 매니저 - 종료
entityManager.close();
}
// 엔티티 매니저 팩토리 - 종료
entityManagerFactory.close();
}
private static void update(EntityManager entityManager) {
//스냅샷 생성 및 영속 상태로 전환
Member member = entityManager.find(Member.class, "identity");
member.update("홍영준", 27);
}
}
그림 순서 설명
- 트랜잭션을 커밋하면 엔티티 매니저 내부에서 먼저 플러시 호출
- 엔티티와 스냅샷을 비교하여 변경된 엔티티 찾기
- 변경된 엔티티가 있으면 수정 쿼리를 생성해서 쓰기 지연 SQL에 저장
- 쓰기 지연 저장소의 SQL을 데이터베이스에 전송
- 데이터베이스 트랜잭션 커밋
변경 감지는 영속 상태의 엔티티에만 적용된다.
엔티티 삭제
이전과 마찬가지로 쓰기 지연 SQL 저장소에 삭제 쿼리를 등록하여 삭제한다.
remove() 메소드를 호출하면 영속성 컨텍스트에서 제거된다.
Member member = entityManager.find(Member.class, "identity");
entityManager.remove(member);
플러시
영속성 컨텍스트의 변경 내용을 데이터베이스 반영
- 직접 호출
- 트랜잭션 커밋 시 플러시 자동 호출
- JPQL 쿼리 실행 시 플러시 자동 호출
영속 상태로 만든 엔티티들은 데이터베이스 반영이 되지 않았기 때문에 쿼리 결과대로 조회가 되지 않는다.entityManager.persist(memberA); entityManager.persist(memberB); entityManager.persist(memberC); //JPQL 실행 query = entityManager.createQuery("select m from Member m", Member.class); List<Member> memberList = query.getResultList();
따라서 쿼리를 실행하기 직전에 영속성 컨텍스트를 플러시해서 데이터베이스에 반영한다.
준영속
준영속 상태의 엔티티는 영속성 컨텍스트가 제공하는 기능을 사용할 수 없다.
- detach(entity) : 특정 엔티티만 준영속 상태 전환
- clear() : 영속성 컨텍스트를 완전히 초기화
- close() : 영속성 컨텍스트를 종료
특징
- 거의 비영속에 가깝다.
- 식별자 값을 가지고 있다.
- 지연 로딩을 할 수 없다.
'Spring JPA' 카테고리의 다른 글
연관관계 매핑 기초 - 8 (0) | 2021.07.06 |
---|---|
엔티티 매핑 - 7 (0) | 2021.07.03 |
영속성 관리 - 5 (0) | 2021.06.26 |
JPA 시작 - 4 (0) | 2021.06.25 |
JPA 소개 - 3 (0) | 2021.06.23 |
댓글