Springboot

EntityManager

devfinger 2025. 11. 4. 13:31

1. private EntityManager entityManager;

  • EntityManager는 JPA의 핵심 인터페이스입니다.
  • 데이터베이스에 대한 CRUD(생성, 조회, 수정, 삭제) 작업을 수행하는 "데이터 접근 매니저" 역할을 합니다.
  • JPA를 통해 Entity 객체를 DB에 저장하거나 업데이트하거나 삭제할 때 항상 EntityManager를 사용합니다.

보통 스프링에서는 이렇게 주입받습니다 👇

 
@PersistenceContext private EntityManager entityManager;

🔹 2. entityManager.merge(persistEntity);

이건 "엔티티 병합(Merge)" 작업을 수행하는 코드입니다.
즉, 준영속(detached) 상태의 엔티티를 영속(persistent) 상태로 전환하여 DB에 반영합니다.

🔸 JPA의 엔티티 상태 4단계 복습:

  1. Transient (비영속)
    → 아직 EntityManager가 모르는 상태 (DB와 전혀 연관 없음)
  2. Persistent (영속)
    → EntityManager가 관리 중이며, 트랜잭션 종료 시 자동으로 DB에 반영됨
  3. Detached (준영속)
    → 원래 영속이었지만 EntityManager의 관리에서 벗어난 상태
  4. Removed (삭제)
    → 삭제 예정 상태

🔹 merge()가 하는 일

예를 들어 이런 코드가 있다고 가정합시다:

 
MyEntity entity = new MyEntity(); entity.setId(1L); entity.setName("변경된 이름"); // entity는 DB에서 읽어온 객체가 아니라 detached 상태임 entityManager.merge(entity);

그럼 merge()는 다음 순서로 작동합니다 👇

  1. DB에서 같은 ID를 가진 영속 객체를 조회
    → 예: SELECT * FROM my_entity WHERE id = 1
  2. 조회된 영속 객체의 필드 값을, 인자로 받은 객체(entity)의 값으로 복사
    → 즉, 변경된 값("변경된 이름")이 영속 객체에 반영됩니다.
  3. 복사된 영속 객체를 반환
    → merge()는 새로운 영속 객체를 반환하고, 인자로 넘긴 객체는 여전히 detached 상태입니다.
  4. 트랜잭션이 커밋되면 DB에 UPDATE 쿼리 실행
    → 최종적으로 DB의 해당 row가 수정됩니다.

🔹 예시

 
@Transactional public void updateEntity(MyEntity detachedEntity) { entityManager.merge(detachedEntity); }

이 코드는

  • DB에서 동일한 id를 가진 엔티티를 찾아옴
  • detachedEntity의 변경 내용을 DB의 엔티티에 반영
  • 트랜잭션이 끝나면 자동으로 UPDATE 쿼리 실행

🔹 주의할 점

  1. merge()는 새로운 영속 객체를 반환합니다.
    → persistEntity 자체가 관리되는 객체가 되는 게 아니라, 내부적으로 새 복사본이 관리됩니다.
  2. merge()는 insert 또는 update를 자동으로 구분합니다.
    • @Id가 DB에 없는 값 → INSERT
    • @Id가 DB에 존재 → UPDATE

✅ 요약

메서드역할특징
persist() 새 엔티티를 저장 비영속 → 영속, 반드시 새로 삽입
merge() 엔티티 병합 준영속 → 영속, 존재 시 UPDATE / 없으면 INSERT
remove() 엔티티 삭제 영속 객체만 삭제 가능
find() 조회 ID로 객체 조회 (영속 상태로 반환)

즉,

 
entityManager.merge(persistEntity);

➡️ "데이터베이스에 이미 존재할 수도 있는 persistEntity를 현재 트랜잭션의 영속 컨텍스트로 병합하고, 변경 내용을 반영한다"
는 뜻입니다.