[SpringBoot] Entity, EntityManager, Entity Manager Factory

나른한 개발자·2026년 1월 13일

f-lab

목록 보기
26/44

Entity

DB에서 영속적으로 저장된 데이터를 자바 객체로 매핑해 '인스턴스 형태'로 존재하는 데이터를 말한다. 데이터 베이스 테이블에 대응하는 자바 객체를 의미한다. 각 클래스 필드가 DB의 행(row)에 해당한다.

spring-boot-starter-data-jpa 의존성을 추가하고 자바 클래스에 @Entity 어노테이션을 붙히면 테이블 - 자바 클래스가 매핑이 된다.

@Entity
public class Account{
	String username;
    String password;
}

@Entity 적용시 주의 사항은 다음과 같다.

  • 기본 생성자는 필수이다 (JPA에서는 DB에서 데이터를 조회한 뒤 리플렉션으로 객체를 생성하기 때문에 기본 생성자가 있어야한다.)
  • final 클래스, enum, interface, inner 클래스에는 사용할 수 없다.
  • 저장할 필드에 final을 사용하면 안된다.

Entity의 생명주기

엔티티에는 4가지 상태가 존재한다.

  • 비영속(new/transient): 영속성 컨텍스트와 전혀 관계가 없는 상태
  • 영속(managed): 영속성 컨텍스트에 저장되어 관리되는 상태
  • 준영속(detached): 영속성 컨텍스트에 저장되었다가 분리된 상태
  • 삭제(removed): 삭제된 상태

EntityManager

EntityManager란 JPA 핵심 인터페이스로, 엔티티 객체들을 관리하는 역할을 한다. 엔티티 매니저는 관리하는 엔티티 객체를 영속 컨텍스트(Persistence Context)에 넣어두고, 객체의 라이프 사이클을 관리 한다.

엔티티 매니저는 일반적으로 개발자가 직접 인스턴스화하지 않고, 스프링 부트와 같은 프레임워크에서 DI(Dependency Injection) 방식으로 주입받아 사용한다.

EntityManagerFactory

엔티티 매니저를 생성하는 팩토리로, 스프링 부트 애플리케이션에서 한번만 생성되며 여러 엔티티 매니저를 생성할 수 있다. 데이터베이스와의 연결정보를 가지고 있으며 영속성 유닛이라고 불리는 설정 단위를 기반으로 엔티티 매니저를 관리한다.

기본적으로 JPA는 하나의 DB당 하나의 엔티티 매니저 팩토리를 사용한다. 따라서 멀티 데이터베이스 환경이라면 각 데이터베이스에 매핑되는 별도의 DataSource와 엔티티 매니저 팩토리를 각각 설정해야 한다.

엔티티 매니저 팩토리는 여러 스레드가 동시에 접근해도 안전하므로 서로 다른 스레드 간에 공유해도 되지만, 엔티티 매니저는 여러 스레드가 동시에 접근하면 동시성 문제가 발생하므로 스레드 간에 절대 공유하면 안된다.

Entity Manager는 스프링에서 싱글톤으로 관리되지 않나?

Entity Manager는 스프링에서 싱글톤으로 관리되지 않나? 그런데 왜 Thread-safe 하지 않을까?

그 이유는 SharedEntityManagerCreator 라는 프록시 객체를 사용하기 때문이다.

  • EntityManager를 빈으로 주입받으면 스프링은 프록시 객체를 대신 주입한다.
  • @Transactional이 시작될 때 스프링이 EntityManager를 생성하고 현재 스레드(ThreadLocal)에 바인딩한다.
  • 프록시 EntityManager의 메서드가 호출되면, 프록시는 ThreadLocal에서 현재 스레드에 바인딩된 EntityManager를 꺼내서 그걸로 실제 작업을 수행한다.
  • @Transactional이 끝나면 해당 EntityManager를 닫고 ThreadLocal에서 제거한다.

왜 이렇게 복잡하게 처리할까?

  • 개발 편의성 확보: 만약 프록시가 없다면 개발자가 직접 EntityManagerFactory에서 매번 createEntityManager()를 호출하고, 트랜잭션이 끝나면 close()를 호출해야 한다. 스프링은 이 번거로운 과정을 추상화해서 빈을 주입받아 쓰되, 내부적으로는 새로운 엔티티 매니저를 생성하여 쓰도록 하는 것이다.
  • 스레드 안정성 확보: EntityManager는 여러 스레드가 동시에 접근하면 동시성 문제가 발생할 수 있다. 하지만 스프링이 제공하는 프록시를 사용하면, 각 스레드(요청)마다 서로 다른 트랜잭션 범위 내의 전용 EntityManager에 연결되므로 멀티스레드 환경에서도 안전하게 사용할 수 있다.


정리

엔티티는 DB 테이블에 맵핑되는 자바 객체이다. 클래스 필드가 데이터베이스의 행이 된다. 엔티티에는 생명주기에 따라 4가지 상태가 있다. 영속성 컨텍스트와 연관이 없는 상태인 비영속, 영속성 컨테이너에 저장되어 관리되는 상태인 영속, 영속성 컨텍스트에 저장되었다가 분리된 상태인 준영속, 삭제된 상태인 삭제이다.
엔티티 매니저는 엔티티 객체를 관리하는 역할을 한다. 엔티티를 영속성 컨텍스트 저장하고 라이프 사이클을 관리한다. 여러 스레드간 공유되면 동시성 문제가 발생할수 있으므로 스레드간 공유해서는 안된다. 엔티티 매니저 팩토리는 엔티티 매니저를 생성하는 팩토리로 스프링에서는 기본적으로 하나의 엔티티매니저 팩토리를 생성한다. 엔티티 매니저 팩토리는 여러 스레드가 동시에 접근해도 안전하여 서로 다른 스레드 간에 공유해도 된다.

profile
Start fast to fail fast

0개의 댓글