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 쿼리)