DB에서 영속적으로 저장된 데이터를 자바 객체로 매핑해 '인스턴스 형태'로 존재하는 데이터를 말한다. 데이터 베이스 테이블에 대응하는 자바 객체를 의미한다. 각 클래스 필드가 DB의 행(row)에 해당한다.
spring-boot-starter-data-jpa 의존성을 추가하고 자바 클래스에 @Entity 어노테이션을 붙히면 테이블 - 자바 클래스가 매핑이 된다.
@Entity
public class Account{
String username;
String password;
}
@Entity 적용시 주의 사항은 다음과 같다.
엔티티에는 4가지 상태가 존재한다.
EntityManager란 JPA 핵심 인터페이스로, 엔티티 객체들을 관리하는 역할을 한다. 엔티티 매니저는 관리하는 엔티티 객체를 영속 컨텍스트(Persistence Context)에 넣어두고, 객체의 라이프 사이클을 관리 한다.
엔티티 매니저는 일반적으로 개발자가 직접 인스턴스화하지 않고, 스프링 부트와 같은 프레임워크에서 DI(Dependency Injection) 방식으로 주입받아 사용한다.
엔티티 매니저를 생성하는 팩토리로, 스프링 부트 애플리케이션에서 한번만 생성되며 여러 엔티티 매니저를 생성할 수 있다. 데이터베이스와의 연결정보를 가지고 있으며 영속성 유닛이라고 불리는 설정 단위를 기반으로 엔티티 매니저를 관리한다.
기본적으로 JPA는 하나의 DB당 하나의 엔티티 매니저 팩토리를 사용한다. 따라서 멀티 데이터베이스 환경이라면 각 데이터베이스에 매핑되는 별도의 DataSource와 엔티티 매니저 팩토리를 각각 설정해야 한다.
엔티티 매니저 팩토리는 여러 스레드가 동시에 접근해도 안전하므로 서로 다른 스레드 간에 공유해도 되지만, 엔티티 매니저는 여러 스레드가 동시에 접근하면 동시성 문제가 발생하므로 스레드 간에 절대 공유하면 안된다.
Entity Manager는 스프링에서 싱글톤으로 관리되지 않나? 그런데 왜 Thread-safe 하지 않을까?
그 이유는 SharedEntityManagerCreator 라는 프록시 객체를 사용하기 때문이다.
왜 이렇게 복잡하게 처리할까?
정리
엔티티는 DB 테이블에 맵핑되는 자바 객체이다. 클래스 필드가 데이터베이스의 행이 된다. 엔티티에는 생명주기에 따라 4가지 상태가 있다. 영속성 컨텍스트와 연관이 없는 상태인 비영속, 영속성 컨테이너에 저장되어 관리되는 상태인 영속, 영속성 컨텍스트에 저장되었다가 분리된 상태인 준영속, 삭제된 상태인 삭제이다.
엔티티 매니저는 엔티티 객체를 관리하는 역할을 한다. 엔티티를 영속성 컨텍스트 저장하고 라이프 사이클을 관리한다. 여러 스레드간 공유되면 동시성 문제가 발생할수 있으므로 스레드간 공유해서는 안된다. 엔티티 매니저 팩토리는 엔티티 매니저를 생성하는 팩토리로 스프링에서는 기본적으로 하나의 엔티티매니저 팩토리를 생성한다. 엔티티 매니저 팩토리는 여러 스레드가 동시에 접근해도 안전하여 서로 다른 스레드 간에 공유해도 된다.