영속성이란 JPA를 공부하면서 많이 접하게 되는 용어이다.
영속성은 JPA가 제공하는 핵심 개념 중 하나로, 데이터베이스와 자바 애플리케이션 간의 데이터 저장과 관리를 의미한다. 이를 통해서 데이터베이스의 레코드를 자바 객체로 다루면서, 객체 지향적인 방법으로 데이터베이스 조작을 할 수 있게 된다.
JPA에서의 영속성에 대해 주요 개념을 추가로 설명해보겠다.
영속성 컨텍스트는 엔티티 객체를 관리하는 일종의 메모리 공간이다. 엔티티 매니저가 이 영속성 컨텍스트를 통해서 엔티티의 상태를 관리한다. 영속성 컨텍스트는 JPA에서 데이터의 일관성을 보장하는 중요한 역할을 하며, 여기서 관리되는 엔티티들은 영속 관계에 놓인다.
JPA
에서 엔티티 객체는 네 가지의 생명주기를 가진다.
비영속 상태 Transient
엔티티 객체가 영속성 컨텍스트와 전혀 연과되어 있지 않은 상태이다. 자바 객체로는 존재하지만, 데이터베이스와 연관되어 있지 않은 상태를 말한다. 예를 들어서 new
키워드를 사용해서 새로 생성한 엔티티는 비영속 상태이다.
영속 상태 Persistent
엔티티가 영속성 컨텍스트에 저장된 상태로, 데이터베이스에 반영될 준비가 된 상태이다. 이 상태에서는 영속성 컨텍스트가 엔티티를 관리하며, 자동으로 변경 사항을 데이터베이스에 반영한다.
예를 들어서 entityManager.persist(entity)
를 호출하면 엔티티가 영속 상태로 전환된다
준영속 상태 Detached
영속성 컨텍스트에 의해 관리되던 엔티티가 더 이상 관리되지 않는 상태이다. 즉 데이터베이스와의 동기화가 끊긴 상태이다.
예를 들어서 entityManger.detach(entity)
를 호출하거나 entityManger.clear()
로 전체 컨텍스트를 비울 때 엔티티가 준영속 상태가 된다.
삭제 상태 Removed
마지막 상태로 엔티티가 영속성 컨텍스트에서 삭제되어 데이터베이스에서도 삭제될 준비가 된 상태이다. entityManager.remove(entity)
를 호출하면 엔티티가 상태 상태가 된다.
아마 엔티티의 생명주기를 읽으면서 나는 EntityManager
를 직접 사용한적이 없는데 생명주기를 이용안한건가?? 라는 생각을 할 수도 있지만 JPA
를 사용한다면 EntityManager
를 내부적으로 사용하면서 개발자가 직접 EntityManger
를 다루지 않고도 쉽게 JPA의 기능을 활용할 수 있도록 도와준다고 한다.
public interface MemberRepository extends JpaRepository<MemberEntity, Long> {
// 기본 CRUD 메서드가 자동으로 제공됨
Optional<MemberEntity> findByUsername(String username);
}
예를 들어서 위의 코드에서는 JpaRepository
인터페이스를 상속받기만 하면 자동으로 EntityManager
를 사용해서 데이터베이스와 상호작용하는 메서드를 제공하기 때문에 EntityManager
를 직접 다룰 필요가 없다
Flush
는 영속성 컨텍스트에 있는 변경 사항을 데이터베이스에 반영하는 작업을 의미한다. 기본적으로 JPA
는 트랜잭션이 커밋되기 전에 플러시를 수행해서 엔티티의 변경사항을 자동으로 데이터베이스에 동기화한다. 개발자가 필요에 따라 flush()
메서드를 호출해서 수동으로 플러시를 할 수도 있다변경 감지 즉 Dirty Checking
이란 용어도 개발을 진행하면서 자주 들었지만 어떤 용어인지는 잘 몰랐던 용어인데, JPA가 영속 상태의 엔티티 객체가 변경되었을 때 자동으로 이를 감지하여, 트랜잭션 커밋 시점에 데이터베이스에 업데이트한다. 이러한 로직을 Dirty Checking
이라고 한다. 이 과정에서 @Entity
객체의 필드 값이 변경되었는지를 추적한다.
Dirty Checking
은 성능을 최적화하고 데이터 일관성을 보장하기 위해 매우 중요한 개념이라고 한다
Lazy Loading
즉 지연 로딩은 위에서도 언급한 용어인데, 연관된 엔티티나 데이터를 실제로 사용할 때 데이터베이스에서 조회하는 방식이다. 필요하지 않은 데이터를 미리 로드하지 않기 때문에 성능 상의 이점이 있다
Eager Loading
은 즉시 로딩이라고 하는데 연관된 엔티티나 데이터를 즉시 데이터베이스에서 가져오는 방식이다. 기본적으로 모든 관련 엔티티가 함께 로드되기 때문에 성능 저하가 발생할 수 있다
두 개의 용어를 언제 사용하냐면 보통 엔티티 관계에서 @OneToMany
와 @ManyToOne
등의 관계를 설정할 때 많이 사용했다.
그래서 만약에 누군가가 너 JPA에서의 영속성
과 영속성 컨텍스트
가 뭐야? 라고 묻는다면
영속성은 데이터를 데이터베이스에 영구적으로 저장되어서 애플리케이션이 종료되더라도 유지되는 것이고, 영속성 컨텍스트란 엔티티 객체를 관리하고 트랜잭션이 진행되는 동안 데이터베이스와의 동기화를 처리하는 메모리 공간이야 정리하자면 영속성 컨텍스트는 애플리케이션이 실행되는 동안만 메모리에서 엔티티 객체를 관리하는 일종의 임시 저장소라 애플리케이션이 종료되면 영속성과 다르게 사라져!!
라고 말할 수 있어야 할 것 같다.