[JPA] 영속성 컨텍스트(Persistence context)와 EntityManager

해니·2023년 6월 13일
0

JPA

목록 보기
3/8
post-thumbnail


영속성 컨텍스트란 (Persistence context)?

  • 엔티티를 영구 저장하는 환경
  • 애플리케이션(응용 프로그램)과 데이터베이스 사이에서 객체를 보관하는 가상의 데이터베이스 같은 역할을 한다.
  • 엔티티 매니저를 통해 엔티티를 저장하거나 조회하면 엔티티 매니저는 영속성 컨텍스트에 엔티티를 보관하고 관리한다.
// Java Persistence API (JPA)를 사용하여 엔티티 매니저 팩토리(EntityManagerFactory)를 생성
// 영속성 유닛(persistence unit)에 대한 엔티티 매니저 팩토리를 생성
EntityManagerFactory emf = Persistence.createEntityManagerFactory("jpabegin");

// 엔티티 매니저를 생성
EntityManager entityManager = emf.createEntityManager();




[출처] JPA & Spring Data JPA 기초




엔티티(Entity)

  • 영속성을 가진 객체로 DB 테이블에 보관할 대상 -> 영속 컨텍스트에 속한 객체
  • @Entity 어노테이션 또는 xml 설정을 통해 엔티티를 설정할 수 있다.



엔티티 매핑 관련 어노테이션


1. @Entity

  • JPA를 사용해 테이블과 매핑할 클래스에 붙여주는 어노테이션
  • 속성
    • name : JPA에서 사용할 엔티티 이름 지정. name 속성을 사용하지 않을 경우 , 클래스이름을 엔티티 이름으로 지정

2. @Table

  • 엔티티와 매핑할 테이블을 지정
  • 속성
    • name : 매핑할 테이블 이름. 생략시 엔티티 이름(@Entity(name="~") 사용
    • catalog : catalog 기능이 있는 DB에서 catalog 매핑
    • schema: schema기능이 있는 DB에서 schema 매핑
    • uniqueContraints : DDL 생성시 유니크 제약조건 생성.(스키마 자동 생성 기능을 사용해 DDL을 만들 때만 사용 )

3. @Id

  • 특정 속성을 기본키로 설정하는 어노테이션
  • @Id 어노테이션만 적게될 경우, 기본키값을 직접 부여해줘야 한다.
    • 보통 DB를 설계할 때는 기본키는 직접 부여하지 않고 Mysql AUTO_INCREMENT처럼 자동 부여되게끔 한다.
  • @GeneratedValue 어노테이션을 사용하면 기본값을 DB에서 자동으로 생성하는 전략을 사용 할 수 있다.

4. @Column

  • 객체 필드를 테이블 컬럼과 매핑한다.
  • 속성
    • name: 필드와 매핑할 테이블의 컬럼 이름 지정. default는 필드이름으로 대체.
    • insertable : true (엔티티 저장시 필드값 저장) , false (필드값이 저장되지 않음)
    • updatable: true (엔티티 수정시 값이 수정) , false (엔티티 수정시 값이 수정 되지 않음)
    • table : 하나의 엔티티를 두 개 이상의 테이블에 매핑할 때 사용
    • nullable : null값 허용 여부 설정
    • unique : 컬럼에 유니크 제약조건 부여
    • columnDefinition : 데이터베이스 컬럼 정보를 직접 부여
    • length : 문자 길이 제약조건. String 타입일 때 사용
    • precision, scale : BigDecimal 타입에서 사용. precision (소수점을 포함한 전체 자릿수 설정)
      scale(소수의 자릿수)



@Entity
@Table(name = "user")
public class User {
    @Id
    private String email;
    private String name;

    @Column(name = "create_date")
    private LocalDateTime createDate;

    protected User() {
    }

    public User(String email, String name, LocalDateTime createDate) {
        this.email = email;
        this.name = name;
        this.createDate = createDate;
    }

    public String getEmail() {
        return email;
    }

    public String getName() {
        return name;
    }

    public LocalDateTime getCreateDate() {
        return createDate;
    }

    public void changeName(String newName) {
        this.name = newName;
    }
}






엔티티매니저(EntityManager)

  • 영속 컨텍스트에 접근하여 엔티티에 대한 DB 작업을 제공한다.
    • DB table과 mapping된 객체인 Entity에 대한 CRUD 작업을 수행하기 위한 method들을 제공한다.
  • Entity의 라이프 사이클과 영속성 관리 등을 담당한다.



엔티티 매니저 팩토리 (EntityManagerFactory)

  • Entity Manager를 만들고 구성하는 법을 제공하는 interface
  • 일반적으로 JPA의 구현체인 Hibernate나 EclipseLink에 의해서 생성되며 Entity Manager 인스턴스를 생성하는데 사용된다.




// EMF.java 

import jakarta.persistence.EntityManager;
import jakarta.persistence.EntityManagerFactory;
import jakarta.persistence.Persistence;

public class EMF {
    private static EntityManagerFactory emf;

    public static void init() {
        emf = Persistence.createEntityManagerFactory("jpabegin"); // (1)
    }

    public static EntityManager createEntityManager() {
        return emf.createEntityManager();
    }

    public static void close() {
        emf.close();
    }
}

(1) persistent.xml에 <persistence-unit> 태그의 name 속성값을 매개변수로 넘긴다.



1. find() 메서드

  • 영속 컨텍스트에서 엔티티를 검색하고 없을 경우 DB에서 데이터를 찾아 영속 컨텍스트에 저장한다.
  • 식별자는 Entity 클래스에서 @Id 애노테이션으로 지정한 값을 사용해야 한다.
  • public find(Class entityClass, Object primaryKey)
public class GetUserService {
    public User getUser(String email) {
        EntityManager em = EMF.createEntityManager();

        User user = em.find(User.class ,email); // (1)

        try {

            if(user == null) {
                throw new NoUserException();
            }

            return user;

        } finally {
            em.close();
        }


    }
}

(1) 엔티티 타입, ID 타입이 일치해야 한다. 일치하지 않은 경우 예외 발생한다.




2. persist() 메서드

  • 엔티티를 영속 컨텍스트에 저장 후 INSERT 쿼리를 실행한다.
  • 보통 커밋시점에 INSERT 쿼리를 실행하는데 바로 실행하는 경우도 존재한다.
  • public void persist(Object entity)
  • 트랜잭션 범위 내에서 실행해야 한다.
    • 실행시점에 영속 컨텍스트에 엔티티를 저장하고, 트랜잭션을 commit() 하는 시점에 insert 쿼리가 실행되므로 트랜잭션 범위에서 실행하지 않는다면 실제로 DB에 반영되지 않는다.
public class NewUserService {

    public void saveNewUser (User user) {

        EntityManager em = EMF.createEntityManager();
        EntityTransaction tx = em.getTransaction(); // (1) 

        try {
            tx.begin();  // (2) 
            em.persist(user); // (3)
            tx.commit(); // (4) 
        } catch (Exception e){
            tx.rollback(); // (5) 
            throw new RuntimeException(e);
        } finally {
            em.close();
        }


    }
}

(1) JPA의 모든 활동은 트랜잭션 안에서 이루지기 때문에 아래와 같이 트랜잭션을 얻는다.
(2) 트랜잭션이 시작된다. 데이터베이스에 접근해서 커넥션을 가지고 온 후 , 실제 트랙잭션을 시작한다.
(3) persist는 영구저장하다라는 의미이다. Entity를 영속성 컨텍스트에 저장한다.
(4) 트랜잭션을 수행한다.
(5) 작업에 문제 발생 시 되돌린다.
(6) EntityManager을 사용한 후에는 항상 close() 메서드를 호출하여 리소스를 해제해주어야 한다. ( 리소스 누수 , 트랙잭션 문제, 지연로딩 문제 등이 발생할 수 있음 .. )





트랜잭션(Transaction)이란? 🙄

  • 데이터베이스의 상태를 변경시키기 위해 수행하는 작업 단위
    • SELECT, UPDATE, INSERT, DELETE 등
  • Atomicity(원자성)
    • 트랜잭션의 연산은 데이터베이스에 모두 반영되거나 전혀 반영되지 않아야 한다. (All or Nothing)
    • 트랜잭션 내의 모든 명령은 반드시 완벽히 수행되어야 하며, 모두가 완벽히 수행되지 않고 어느하나라도 오류가 발생하면 트랜잭션 전부가 취소되어야 한다.

1) 트랜잭션의 성질

  • Consistency(일관성)

    • 트랜잭션 작업 처리의 결과가 항상 일관되어야 한다
    • 트랜잭션 수행 전과 후 데이터 타입이 동일해야 한다.
  • Isolation(독립성,격리성)

    • 각각의 트랜잭션은 독립적이라 서로 간섭이 불가능하다.
    • 둘 이상의 트랜잭션이 동시에 병행 실행되는 경우 어느 하나의 트랜잭션 실행중에 다른 트랜잭션의 연산이 끼어들 수 없다.
    • 수행중인 트랜잭션은 완전히 완료될 때까지 다른 트랜잭션에서 수행 결과를 참조할 수 없다.
  • Durablility(영속성,지속성)

    • 트랜잭션이 성공적으로 완료되면 영구적으로 결과에 반영되어야 한다.
    • 일반적으로 commit 이 된다면 지속성을 만족할 수 있다.

2) 트랜잭션 연산 및 상태

  • Commit연산
    • 하나의 트랜잭션이 성공적으로 끝나서 데이터베이스가 일관성있는 상태에 있음을 의미한다.
  • Rollback 연산
    • 트랜잭션의 원자성이 깨질 때, 즉 하나의 트랜잭션 처리가 비정상적으로 종료 되었을 때의 상태를 의미한다.
    • Rollback 이 이뤄진다면 트랜잭션을 다시 실행하거나 부분적으로 변경된 결과를 취소할 수 있다.






출처
https://dundung.tistory.com/220
https://perfectacle.github.io/2018/01/14/jpa-entity-manager-factory/
https://onejunu.tistory.com/24
https://dev-troh.tistory.com/151
https://cjw-awdsd.tistory.com/46
JPA 2강 - JPA기초와 매핑 https://nanci.tistory.com/87
[DB기초] 트랜잭션이란 무엇인가? https://coding-factory.tistory.com/226
[데이터베이스] Transaction, 트랜잭션이란? https://wonit.tistory.com/462

profile
💻 ⚾️ 🐻

0개의 댓글