1. 엔티티 그래프 소개
- JPA 2.1에 추가된 기능으로, 객체 지향 쿼리를 사용하지 않고도 엔티티를 조회하는 시점에 함께 조회할 연관된 엔티티를 선택할 수 있다.
- 엔티티 그래프는 항상 조회하는 엔티티의 루트에서 시작해야 한다.
- 글로벌 fetch 전략보다 우선 순위가 높다.
- 영속성 컨텍스트에 이미 로딩되어 있는 엔티티에 대해서는 엔티티 그래프가 적용되지 않는다. 아직 초기화되지 않은 프록시에는 엔티티 그래프가 적용된다.
- 엔티티 그래프는 정적으로 정의하는 Named 엔티티 그래프와 동적으로 정의하는 엔티티 그래프가 있다.
2. Named 엔티티 그래프
1) Named 엔티티 그래프 정의
- @NamedEntityGraph 어노테이션으로 정의한다. name 속성에는 엔티티 그래프의 이름을 지정하고, attributeNodes 속성에는 함께 조회할 필드를 @NamedAttributeNode 어노테이션을 사용하여 선택하면 된다.
@NamedEntityGraph(name="Order.withMember", attributeNodes={
@NamedAttributeNode("member")
})
@Entity
public class Order {
...
@ManytoOne(fetch=FetchType.LAZY, optional=false)
@JoinColumn(name="MEMBER_ID")
private Member member;
}
※ 둘 이상의 @NamedEntityGraph를 정의하려면 @NamedEntityGraphs를 사용한다.
2) EntityManager.find()에서 엔티티 그래프 사용
- EntityManager.getEntityGraph() 메소드의 파라미터로 엔티티 그래프의 이름을 넣으면 EntityGraph 객체를 반환한다. 이 EntityGraph 객체를 Map에 넣어 힌트를 만들 수 있다.
EntityGraph graph = em.getEntityGraph("Order.withMember");
Map hints = new HashMap();
hints.put("javax.persistence.fetchgraph", graph);
Order order = em.find(Order.class, orderId, hints);
※ javax.persistence.fetchgraph 속성은 엔티티 그래프에 선택한 속성만 함께 조회하고, javax.persistence.loadgraph 속성은 엔티티 그래프에 선택한 속성뿐만 아니라 글로벌 fetch 모드가 FetchType.EAGER로 설정된 연관관계까지 함께 조회한다는 차이가 있다.
3. 서브 그래프
- 서브 그래프를 이용하면 엔티티 필드의 하위 연관관계까지 선택할 수 있다.
- @NamedEntityGraph의 subgraphs 속성에 서브 그래프를 지정한다.
- 아래 예시에서는 Order -> OrderItem -> Item 엔티티까지 함께 조회한다.
@NamedEntityGraph(name="Order.withAll",
attributeNodes={
@NamedAttributeNode("member"),
@NamedAttributeNode(value="orderItems", subgraph="orderItems") // List<OrderItem> orderItems
},
subgraphs=@NamedSubgraph(name="orderItems", attributeNodes={@NamedAttributeNode("item")}) // Item item
)
4. JPQL에서 엔티티 그래프 사용
- setHint() 메소드로 EntityGraph를 추가한다.
List<Order> resultList = em.createQuery("SELECT o FROM Order o WHERE o.id=:orderId", Order.class)
.setParameter("orderId", orderId)
.setHint("javax.persistence.fetchgraph", em.getEntityGraph("Order.withAll"))
.getResultList();
- JPQL에서 엔티티 그래프를 사용할 때는 항상 SQL 외부 조인을 사용하기 때문에, 만약 SQL 내부 조인을 사용하려면 내부 조인을 명시해야 한다.
SELECT o FROM Order o JOIN FETCH o.member WHERE o.id=:orderId
5. 동적 엔티티 그래프
- EntityManager.createEntityGraph() 메소드를 사용한다.
public <T> EntityGraph<T> createEntityGraph(Class<T> rootType);
- EntityGraph.addAttributeNodes() 메소드로 연관관계를 엔티티 그래프에 포함한다. 서브 그래프의 경우에는 EntityGraph.addSubgraph() 메소드로 추가하면 된다.
EntityGraph<Order> graph = em.createEntityGraph(Order.class);
graph.addAttributeNodes("member");
Subgraph<OrderItem> orderItems = graph.addSubgraph("orderItems");
orderItems.addAttributeNodes("item");
Map hints = new HashMap();
hints.put("javax.persistence.fetchgraph", graph); // 루트 엔티티 그래프
Order order = em.find(Order.class, orderId, hints);
● 참고자료 : 자바 ORM 표준 JPA 프로그래밍
'Spring 사전 준비 > JPA Hibernate' 카테고리의 다른 글
[JPA] 성능 최적화 (0) | 2022.08.27 |
---|---|
[JPA] JPA 예외 처리 (0) | 2022.08.25 |
[JPA] JPA 리스너 (0) | 2022.08.24 |
[JPA] Entity와 Table간의 데이터 타입 변환 (0) | 2022.08.24 |
[JPA] JPA와 컬렉션 (0) | 2022.08.24 |
댓글