@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)이란?