Miracle Morning, LHWN

1. 엔티티 (Entity) 와 엔티티 매니저 (Entity Manager) 본문

IT 기술/[JAVA] Spring Boot

1. 엔티티 (Entity) 와 엔티티 매니저 (Entity Manager)

Lee Hye Won 2021. 5. 5. 10:15

엔티티 매니저

 

특정 작업을 위해 데이터베이스에 액세스하는 역할을 담당한다.

엔티티를 DB 에 등록/수정/삭제/조회(CRUD) 하는 역할이며, 엔티티와 관련된 일을 처리하는 엔티티 관리자이다.

 

- 엔티티 매니저 팩토리는 설정 정보를 읽어와 DB 커넥션 풀도 생성하기 때문에 엔티티 매니저 팩토리를 생성하는 비용이 크다.

따라서 엔티티 매니저 팩토리는 어플리케이션 전체에서 딱 한번만 생성하고 공유해서 사용해야 한다.

- 엔티티 매니저는 데이터베이스 커넥션과 밀접한 관계가 있으므로 스레드간에 공유하거나 재사용하면 안된다.

- 사용이 끝난 엔티티 매니저는 반드시 종료해야 한다.

 

엔티티 매니저 팩토리 엔티티 매니저
엔티티 매니저 팩토리는 생성 비용이 크기 때문에
DB 를 하나만 사용하는 어플리케이션이라면 일반적으로 하나만 만든다.
엔티티 매니저 팩토리를 이용해서 생성한다.
스레드 세이프하기 때문에 여러 스레드가 동시 접근해도 안전하다. 여러 스레드가 동시에 접근하면 동시성 문제가 발생하기 때문에
공유해서는 안된다.

# 영속성 컨텍스트 (Persistence context)

- 영구 저장 환경이다.

- 엔티티 매니저가 엔티티를 저장하거나 조회하면 매니저는 영속성 컨텍스트에 엔티티를 보관하고 관리한다.

- 엔티티 매니저가 persist() 메서드를 사용하면 엔티티를 영속성 컨텍스트에 저장한다.

- 하나의 엔티티 매니저가 하나의 영속성 컨텍스트를 생성 및 접근할 수도 잇고, 

여러 엔티티 매니저가 하나의 영속성 컨텍스트를 공유할 수도 있다.

 

# 엔티티의 생명주기

1. 비영속 (new/transient) : 영속성 컨텍스트와 관계가 없는 상태

2. 영속 (managed) : 영속성 컨텍스트에 저장된 상태

3. 준영속 (detached) : 영속성 컨텍스트에 저장되어있다가 분리된 상태

4. 삭제 (removed) : 삭제된 상태

 

https://fastcampus.co.kr/courses/204729/clips/

- 영속성 컨텍스트는 엔티티를 식별자 값(@Id annotation) 으로 구분하기 때문에 영속 상태는 식별자 값이 반드시 필요하다.

- JPA 는 보통 트랜잭션을 커밋하는 순간 영속성 컨텍스트의 엔티티를 데이터베이스에 반영한다. 이러한 동작을 flush 라고 한다.

- 영속성 컨텍스트가 엔티티를 관리할 때 생기는 장점은 아래와 같다.

  1. 1차 캐시
  2. 동일성 보장
  3. 트랜잭션을 지원하는 쓰기 지연
  4. 변경 감지
  5. 지연 로딩 (Lazy Loading)

# flush

flush 는 영속성 컨텍스트의 변경 내용을 데이터베이스에 반영한다. flush 를 수행하면 아래와 같이 동작한다.

(1) 변경 감지가 동작하여 영속성 컨텍스트에 있는 모든 엔티티를 스냅샷과 비교하여 변경이 있는 엔티티를 찾는다.

(2) 변경이 있는 엔티티는 수정 쿼리를 만들어 쓰기 지연 SQL 저장소에 등록한다.

(3) 쓰기 지연 SQL 저장소의 쿼리를 데이터베이스에 전송한다.

 

# 영속성 컨텍스트를 플러시하는 방법

  1. em.flush() 를 직접 호출
  2. 트랜잭션 커밋 시 자동 호출
  3. JPQL 쿼리 실행 시 자동 호출

@Entity

테이블과 매핑할 클래스에 필수로 사용되는 annotation 로 @Entity 가 붙은 클래스는 JPA 가 관리한다.

name 속성을 이용하여 JPA 에서 사용할 엔티티 이름을 지정한다. 설정하지 않으면 기본 값으로 클래스 이름이 된다.

다른 패키지에 이름이 같은 엔티티 클래스가 있을 경우 이름을 지정하여 충돌을 피한다.

 

단, 기본 생성자는 필수이다. (파라미터가 없는 public 혹은 protected 생성자)

final 클래스, enum, interface, inner 클래스에는 사용할 수 없다. 저장할 필드에 final 을 사용하면 안된다.

 

@Data
@Entity
@Table(name="Users")
public class User {
    @Id
    @Column(name="id")
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    
    ...
    
}

@Table

엔티티와 매핑할 테이블을 지정한다. 생략할 경우 매핑한 엔티티 이름을 테이블 이름으로 사용한다.

속성 기능
name 매핑할 테이블 이름 (기본 값은 엔티티 이름
catalog catalog 기능이 있는 DB 에서 catalog 를 매핑
schema schema 기능이 있는 DB 에서 schema 를 매핑

# 필드와 컬럼 매핑

annotation 설명
@Column 컬럼을 매핑한다. 
name 속성을 이용하여 매핑할 컬럼을 지정한다. (디폴트는 개체의 필드 이름)
@Enumerated Java 의 enum 타입을 매핑한다.
value 속성을 이용하여 DB 에 저장할 값을 지정한다.
- EnumType.ORDINAL : enum 의 순서를 DB 에 저장 (Default)
- EnumType.STRING : enum 의 이름을 저장
@Temporal 날짜 타입을 매핑한다.
value 속성을 이용하여 DB 에 값을 저장해야 한다. value 속성은 필수이다.
- TemporalType.DATE : 날짜, DB 의 date 타입과 매핑
- TemporalType.TIME : 날짜, DB 의 time 타입과 매핑
- TemporalType.TIMESTAMP : 날짜와 시간, DB 의 timestamp 타입과 매핑
@Lob  BLOB, CLOB 타입을 매핑한다.
@Transient 특정 필드를 데이터베이스에 매핑하지 않는다.

 

출처 : fastcampus.co.kr/courses/204729/clips/

'IT 기술 > [JAVA] Spring Boot' 카테고리의 다른 글

5. 객체지향 쿼리언어_2  (0) 2021.05.06
4. 객체지향 쿼리언어_1  (0) 2021.05.06
3. 프록시와 연관관계  (0) 2021.05.05
2. 연관관계매핑  (0) 2021.05.05
0. ORM 과 JPA 에 대해  (0) 2021.05.05
Comments