
영속성 컨텍스트: JPA의 중요한 특징 중 하나로, 엔티티를 관리하는 가상의 공간.
-> 이것을 통해 데이터베이스에서 효과적으로 데이터를 가져올 수 있고, 엔티티를 편하게 사용할 수 있다.
(캐시의 키는 엔티티의 @Id 애너테이션이 달린, 기본키 역할을 하는 식별자. 값은 엔티티)
ex)
INSERT INTO ... VALUES (1)
INSERT INTO ... VALUES (2)
INSERT INTO ... VALUES (3)
이 쿼리는 데이터 추가 쿼리가 3개인데, 영속성 컨텍스트는 쿼리를 3번 실행하지 않고 트랜잭션을 커밋하는 시점에 3개의 쿼리를 한꺼번에 전송한다.
-> 적당한 묶음으로 쿼리를 요청할 수 있어 데이터베이스 시스템의 부하를 줄일 수 있다.
지연로딩을 공부하며 "필요한 순간"이란 언제고, 어떻게 판별하는지 궁금했는데 이는
프록시 객체를 통해 실제 데이터에 접근하는 순간을 의미한다.
쉽게말해, 해당 엔티티의 연관된 데이터를 사용할 때 이다.
@Entity
public class Member {
@Id
private Long id;
@ManyToOne(fetch = FetchType.LAZY)
private Team team;
}
위 코드에서 member.getTeam()을 호출하기 전에는 Team객체를 프록시로 가지고 있다.
member.getTeam().getName()처럼 실제로 team의 "속성"에 접근하는 순간에 영속성 컨텍스트가 해당 team을 로딩할 필요성을 느끼고 쿼리를 보낸다.
참고: How does a JPA Proxy work and how to unproxy it with Hibernate
참고: How proxy loads the lazy property in Hibernate/JPA
참고: Eager/Lazy Loading in Hibernate : 스프링 공식문서
이와 반대로 즉시 로딩이라는 개념도 있다. 이는 쿼리를 보내 연과된 엔티티도 함께 조회하는 방식이다.
또한 스프링 공식문서에서는 "Hibernate에서는 프록시를 비활성화하거나 지연 로딩을 끄고 모든 데이터를 한 번에 불러오는 것을 좋지 않은 관행으로 간주됩니다. 필요 여부와 관계없이 많은 양의 데이터를 가져오고 저장하게 될 수 있습니다." 라는 말도 있다.
해당 글은 다음 도서의 내용을 정리하고 참고한 글임을 밝힙니다.
신선영, ⌜스프링 부트 3 벡엔드 개발자 되기 - 자바 편⌟, 골든래빗(주), 2023, 384쪽