@Transactional 어노테이션을 사용하면 save 메소드를 사용하지 않아도 된다고? 🤔
JPA로 API 구현 과제를 진행 중이었는데, 지인 개발자가 위와 같은 말을 해줬다.당시에는 '그렇구나~'하고 넘어갔는데 면접에서 비슷한 질문을 받고 답변을 제대로 하지 못 해서 관련 개념을 정리해 보려고 한다.
dirty는
“엔티티 데이터의 변경된 부분”을 뜻하며 dirty
checking은 변경된 부분을 감지한다는 의미이다.save
메소드를 사용하지 않아도 JPA에 의해 변경 사항이 자동으로 데이터베이스에 적용된다.🔎 엔티티 매니저(EntityManager)
🔎 영속성 컨텍스트
EntityManager
)를 통해 엔티티를 저장하거나 조회하면 엔티티 매니저는 영속성 컨텍스트에 엔티티를 보관하고 관리하게 된다.Snapshot
)을 만들어 놓는다. 그리고 트랜잭션이 끝나는 시점에는 이 스냅샷과 비교해서 다른점이 있다면 Update Query
를 데이터베이스로 전달한다.🔎 스냅샷(Snapshot)
🔎 영속(managed)
@Autowired
private EntityManager entityManager;
// Class내에 Autowired로 EntityManager추가
// 객체만 생성한 비영속상태 (엔티티 객체를 생성하였지만 아직 영속성 컨텍스트에 저장하지 않은 상태)
User user = new User();
// 객체를 저장한 영속상태
entityManager.persist(user);
🔎 준영속 상태(detach)
entityManager.detach()
를 호출한다. // 영속 -> 준영속
// user엔티티를 영속성 컨텍스트에서 분리하면 준영속 상태가 된다.
entityManager.detach(user);
// 영속성 콘텍스트를 비우면 관리되고 있던 엔티티들은 준영속 상태가 된다. (대기 상태에 있는 변경 데이터들도 삭제)
entityManager.clear();
// 영속성 콘텍스트를 종료해도 관리되던 엔티티들은 준영속 상태가 된다.
entityManager.close();
// 준영속 -> 영속
// detach를 하여 준영속상태에 빠진 entity를 merge를 하면 다시 영속 상태가 된다.
entityManager.merge(user);
@Transactional
을 사용하여 더티 체킹을 수행할 수 있다.@Service
public class ExampleService {
@Transactional
public void updateInfo(Long id, String name) {
User user = userRepository.findById(id);
user.setName(name);
}
}
🔔 변경 부분만 update하고 싶은 경우에는?
update
쿼리는 기본적으로 모든 필드를 업데이트한다.@DynamicUpdate
어노테이션을 사용한다@DynamicUpdate
를 선언해주기만 하면된다.@Getter
@NoArgsConstructor
@Entity
@DynamicUpdate // 변경한 필드만 대응
public class Pay {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String tradeNo;
private long amount;
}
출처
[JPA] 더티 체킹(dirty checking) 정리
[JPA] JPA의 UPDATE방식과 Dirty Checking
[JPA] 더티 체킹(Dirty Checking)
더티 체킹(Dirty Checking)이란?
Jpa EntityManager 설명 (영속성 컨텍스트)
[JPA] 영속성 컨텍스트란?
[JPA] 준영속 상태(detach)
[Spring JPA] 영속성 컨텍스트(Persistence Context)
JPA 더티 체킹(Dirty Checking)이란?