오늘은 영속성 컨텍스트와 관련된 개념을 학습했다. 영속성 컨텍스트는 JPA에서 Entity 객체를 관리하고, 데이터베이스와의 상호작용을 효율적으로 처리하는 중요한 개념이다.
영속성 컨텍스트란, Entity 객체를 효율적으로 관리하기 위해 JPA에서 제공하는 공간이다. 이 컨텍스트에 저장된 객체들은 JPA에 의해 관리되며, 개발자가 직접 SQL을 작성하지 않고도 데이터를 저장, 조회, 수정, 삭제할 수 있게 해준다.
영속성 컨텍스트는 Entity 객체를 DB와 직접 연결하지 않고, 중간에서 관리하는 역할을 한다. 이를 통해 JPA는 데이터베이스와의 작업을 더 효율적으로 수행할 수 있다.
EntityManager는 영속성 컨텍스트에 접근해 Entity 객체를 조작할 수 있게 해주는 관리자 역할을 한다. 이를 사용하여 Entity 객체를 저장, 조회, 수정, 삭제할 수 있다.
EntityManagerFactory emf = Persistence.createEntityManagerFactory("memo");
EntityManager em = emf.createEntityManager();
EntityManagerFactory는 애플리케이션 실행 시 하나만 생성되며, 데이터베이스에 대한 정보를 기반으로 EntityManager를 생성하는 역할을 한다. persistence.xml 파일에 저장된 데이터베이스 연결 정보를 바탕으로 EntityManagerFactory를 생성할 수 있다.
<persistence-unit name="memo">
<class>com.sparta.entity.Memo</class>
<properties>
<property name="jakarta.persistence.jdbc.driver" value="com.mysql.cj.jdbc.Driver"/>
<property name="jakarta.persistence.jdbc.user" value="root"/>
<property name="jakarta.persistence.jdbc.password" value="your_password"/>
<property name="jakarta.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/memo"/>
<property name="hibernate.hbm2ddl.auto" value="create" />
<property name="hibernate.show_sql" value="true"/>
</properties>
</persistence-unit>
트랜잭션은 여러 SQL 작업을 하나로 묶어 일괄적으로 처리하는 개념이다. 트랜잭션 내의 모든 작업이 성공하면 commit을 통해 데이터베이스에 영구적으로 반영되지만, 중간에 하나라도 실패하면 rollback을 통해 모든 작업이 취소된다.
JPA에서도 이 트랜잭션 개념을 사용하여 데이터를 안전하게 관리한다.
START TRANSACTION; # 트랜잭션을 시작합니다.
INSERT INTO memo (id, username, contents) VALUES (1, 'Robbie', 'Robbie Memo');
COMMIT; # 트랜잭션을 커밋합니다.
JPA에서 트랜잭션을 적용하려면 EntityManager에서 EntityTransaction을 가져와 사용한다. 트랜잭션을 시작하고, 모든 작업이 성공적으로 완료되면 commit을 호출하여 데이터베이스에 반영하고, 오류가 발생하면 rollback을 호출하여 작업을 취소한다.
@Test
@DisplayName("EntityTransaction 성공 테스트")
void test1() {
EntityTransaction et = em.getTransaction(); // 트랜잭션을 가져옵니다.
et.begin(); // 트랜잭션을 시작합니다.
try {
Memo memo = new Memo(); // 저장할 Entity 객체 생성
memo.setId(1L); // 식별자 설정
memo.setUsername("Robbie");
memo.setContents("영속성 컨텍스트와 트랜잭션 이해하기");
em.persist(memo); // Entity 저장
et.commit(); // 트랜잭션 커밋
} catch (Exception ex) {
et.rollback(); // 오류 시 롤백
} finally {
em.close(); // EntityManager 종료
emf.close(); // EntityManagerFactory 종료
}
}
@Test
@DisplayName("EntityTransaction 실패 테스트")
void test2() {
EntityTransaction et = em.getTransaction(); // 트랜잭션을 가져옵니다.
et.begin(); // 트랜잭션을 시작합니다.
try {
Memo memo = new Memo();
memo.setUsername("Robbert"); // 식별자 없이 저장 시도
memo.setContents("실패 케이스");
em.persist(memo); // Entity 저장
et.commit(); // 트랜잭션 커밋
} catch (Exception ex) {
et.rollback(); // 식별자 누락으로 롤백
} finally {
em.close();
emf.close();
}
}
식별자 없이 저장을 시도했기 때문에 오류가 발생하고, 트랜잭션이 rollback되어 DB에 반영되지 않는다.
이번 학습을 통해 영속성 컨텍스트가 어떻게 작동하고, EntityManager와 트랜잭션을 통해 JPA가 데이터베이스와 상호작용하는 방식을 알게 되었다. JPA는 데이터를 효율적으로 관리할 수 있도록 도와주며, 트랜잭션을 통한 안전한 데이터 관리도 가능하다.