CRUD과정을 효율적으로 처리하기 위해 JPA는 영속성 컨텍스트에 Entity객체들을 저장하여 관리하면서 DB와 소통함
영속성 컨텍스트에 접근하여 Entity 객체들을 조작하기 위해서는 EntityManager가 필요
개발자들은 EntityManager를 사용해 Entity를 CRUD 할 수 있음.
EnityManage는 EntityManagerFactory를 통해 생성
3) EntityManagerFactory
: 한 DB당 하나만 생성되어 애플리케이션이 동작하는 동안 사용됨
EntityManagerFactory를 만들기 위해서는 DB에 대한 정보를 전달해야 됨.
/resources/META-INF/위치에persistence.xml파일을 만들어 정보를 넣어두면 정보 전달할 수 있음
/resource/META-INF/ 위치에 persistence.xml 파일을 만들어 정보를 넣어두면 해당 정보를 읽음.
xml파일의 정보를 토대로 Persistence라는 클래스에 의해서 EntityManagerFactory가 만들어짐
EntityManagerFatory에 의해 EntityManager 생성
4) 트랜잭션
: DB 데이터들을 안전하게 관리하기 위해 생겨난 개념
여러 개의 SQL이 하나의 트랜잭션에 포함될 수 있다는 것이 가장 큰 특징
모든 SQL이 성공적으로 수행되면 DB에 영구적으로 반영. SQL 중 단 하나라도 실패한다면 모든 변경 되돌림.
영속성 컨텍스트에 Entity 객체를 저장했다고 해서 DB에 바로 반영되지 ❌
영속성 컨텍스트로 관리하고 있는 변경이 발생한 객체들의 정보를 ActionQueue에 전부 가지고 있다가 마지막에 한 번에 요청해 변경 반영
@Test
@DisplayName("EntityTransaction 성공 테스트")
void test1() {
EntityTransaction et = em.getTransaction(); // EntityManager 에서 EntityTransaction 을 가져옵니다.
et.begin(); // 트랜잭션을 시작합니다.
try { // DB 작업을 수행합니다.
Memo memo = new Memo(); // 저장할 Entity 객체를 생성합니다.
memo.setId(1L); // 식별자 값을 넣어줍니다.
memo.setUsername("Robbie");
memo.setContents("영속성 컨텍스트와 트랜잭션 이해하기");
em.persist(memo); // EntityManager 사용하여 memo 객체를 영속성 컨텍스트에 저장합니다.
et.commit(); // 오류가 발생하지 않고 정상적으로 수행되었다면 commit 을 호출합니다.
// commit 이 호출되면서 DB 에 수행한 DB 작업들이 반영됩니다.
} catch (Exception ex) {
ex.printStackTrace();
et.rollback(); // DB 작업 중 오류 발생 시 rollback 을 호출합니다.
} finally {
em.close(); // 사용한 EntityManager 를 종료합니다.
}
emf.close(); // 사용한 EntityManagerFactory 를 종료합니다.
}
et.begin() : 트랜잭션을 시작하는 명령어
et.commit() : 트랜잭션의 작업들을 영구적으로 DB에 반영하는 명령어
et.rollback() : 오류가 발생했을 때 트랜잭션의 작업을 모두 취소하고 이전 상태로 되돌리는 명령어
Entity 클래스는 DB에 매핑이 되는 것이기 때문에 조심스럽게 다뤄야 함. 그러므로 setter는 필요한 곳에만 달아줘야 함.
5) 영속성 컨텍스트의 기능
1차 캐시
영속성 컨텍스트는 내부적으로 "캐시 저장소"라는 것을 가지고 있음
저장하는 Entity 객체들이 1차캐시(캐시 저장소)에 저장됨
캐시 저장소는 Map 자료구조 형태로 되어있음.
key ➡️ @Id로 매핍한 기본키(식별자 값) 저장
value ➡️ 해당 Entity 클래스의 객체 저장
영속성 컨텍스트는 캐시 저장소 Key에 저장한 식별자값을 사용하여 Entity 객체를 구분하고 관리