EntityManager
JPA에서 엔티티를 관리하는 인터페이스
DB와의 연결을 통해 CRUD를 처리하고, 영속성 컨텍스트(1차 캐시)를 관리한다.
Spring + JPA 환경에서는 트랜잭션이 시작되면(@Transactional이 적용된 메서드가 실행되면) EntityManager가 자동으로 주입된다.
flush()
영속성 컨텍스트의 변경 내용을 DB에 반영(트랜잭션은 계속 유지)
- insert 쿼리 실행
- @GeneratedValue(strategy = GenerationType.IDENTITY)로 설정되지 않은 경우, 생성된 ID를 얻기 위해 미리 insert가 필요할 때 사용
- @GeneratedValue(strategy = GenerationType.IDENTITY)로 설정하면 persist() 호출 시 ID를 얻기 위해 바로 insert 실행 됨
detach()
특정 객체만 더 이상 JPA가 관리하지 않게 만드는 메서드
- 변경 감지를 하고 싶지 않을 때 사용
- 트랜잭션 안에 있더라도 더 이상 DB에 반영되지 않음
실무에서 거의 사용하지 않음 (flush(), clear()로 객체 관리)
clear()
영속성 컨텍스트 전체 초기화 (EntityManager 초기화)
- entityManager를 새로 만들지 않고 메모리를 효율적으로 초기화
실무에서 대량 insert / update 작업에서 필수적으로 사용
ex. 1000건씩 배치 처리하면서 clear()로 중간마다 정리
merge()
영속 상태가 아닌 객체를 DB에 반영
- 대부분 JPA가 관리하는 영속 상태 객체만 다루기 때문에 merge()는 잘 사용하지 않음
- 외부에서 받은 데이터(DTO)는 영속 상태가 아니므로, 해당 데이터를 저장하거나 갱신할 때 주로 사용
@PostMapping("/save")
public void save(@RequestBody MemberDto dto) {
Members m = new Members();
m.setId(dto.getId()); // ← ID가 존재하면 update / 존재하지 않으면 insert
m.setName(dto.getName());
em.merge(m); // → 이 객체는 영속 상태가 아님. merge로 반영
}
// detached 상태가 된 member
Members member = em.find(Members.class, 1L);
em.detach(member); // JPA 더이상 관리 안 함
member.setName("수정된 이름");
// 다시 저장하려면?
em.merge(member); // → DB 반영됨 (update 쿼리)