엔티티 그래프
엔티티 조회시점에 연관된 엔티티들을 함께 조회하는 기능이다.
- Named 엔티티 그래프
//둘 이상 정의하려면 @NamedEntityGraphs 사용.
@NamedEntityGraph(name = "Order.withMember",
attribueNodes = {
@NamedAttributeNode("member")
})
@Entity
public class Order {
....
@ManyToOne(fetch = FetchType.LAZY, optional = false)
@JoinColumn(name = "MEMBER_ID")
private Member member;
...
}
사용
EntityGraph graph = em.getEntityGraph("Order.withMember");
Map hints = new HashMap();
hints.put("javax.persistence.fetchgraph", graph);
Order order = em.find(Order.class, orderId, hints);
- 서브 그래프
order.orderitem.item 과 같이 여러 단계를 탐색 할때 사용한다.
@NamedEntityGraph(name = "Order.withAll",
attribueNodes = {
@NamedAttributeNode("member"),
@NamedAttributeNode(value="orderItems, subgraph="orderItems")
},
subgraphs = @NamedSubgraph(name="orderItems", attributeNodes={
@NamedAttributeNode("item")
}
//orderItems컬렉션에 담고있는 OrderItem클래스는 item이라는 필드로 Item클래스를 가진다.
)
@Entity
public class Order {
....
@ManyToOne(fetch = FetchType.LAZY, optional = false)
@JoinColumn(name = "MEMBER_ID")
private Member member;
@OneToMany(mappedBy="order")
private List<OrderItem> orderItems = new ArrayList<OrderItem>();
...
}
사용
Map hints = new HashMap();
hints.put("javax.persistence.fetchgraph", em.getEntityGraph("Order.withAll"));
Order order = em.find(Order.class, orderId, hints);
//jpql 에서 사용
List<Order> list = 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();
동적 엔티티 그래프
//그래프 생성
EntityGraph<Order> graph = em.createEntityGraph(Order.class);
//그래프에 member 필드를 가져오도록 추가
graph.addAttributeNodes("member");
//서브 그래프 추가
SubGraph<OrderItem> orderItems = graph.addSubgraph("orderItems");
//서브 그래프에 item 필드 가져오도록 추가
orderItems.addAttributeNodes("item");
Map hints = new HashMap();
hints.put("javax.persistence.fetchgraph", graph);
Order order = em.find(Order.class, orderId, hints);
- 그래프는 무조건 조회할 엔티티 ROOT 에서 시작해야 한다.
- 이미 같은 아이디 값으로 엔티티를 조회 한 후, 그래프를 적용해서 엔티티를 다시 조회하면, 그래프가 적용된 엔티티를 리턴하지 않고, persistence context에 있는 기존 엔티티를 리턴해주므로 그래프가 적용되지않는다.
같은 persistence context 안에서는 이미 조회된 엔티티가 아닌 프록시 엔티티가 존재 하더라도 프록시를 리턴한다. em.getReference(Member.class, memberId);//프록시 객체 가져옴 em.find(Member.class, memberId);//컨텍스트에 존재하는 프록시 그대로 리턴 두 찾아온 객체의 동일성 비교는 같다. (반대의 경우에도 동일)
엔티티 상속 모델을 사용하고, 상속모델을 프록시로 조회하면, 프록시 객체는 해당 실제 엔티티 만을 상속받기 때문에, 다른상속모델을 instanceof 비교하면 false 이다.
같은 persistence context 안에서는 이미 조회된 엔티티가 아닌 프록시 엔티티가 존재 하더라도 프록시를 리턴한다.
em.getReference(Member.class, memberId);//프록시 객체 가져옴
em.find(Member.class, memberId);//컨텍스트에 존재하는 프록시 그대로 리턴
두 찾아온 객체의 동일성 비교는 같다. (반대의 경우에도 동일)
엔티티 상속 모델을 사용하고, 상속모델을 프록시로 조회하면, 프록시 객체는 해당 실제 엔티티 만을 상속받기 때문에, 다른상속모델을 instanceof 비교하면 false 이다.
'JAVA' 카테고리의 다른 글
JPA 락 처리 (0) | 2021.04.28 |
---|---|
JPA 성능 최적화 (0) | 2021.04.28 |
JPA 엔티티 생명주기에 리스너 등록 (0) | 2021.04.28 |
JPA Entity와 DB값 간 매핑 (0) | 2021.04.28 |
JPA 지연로딩 (0) | 2021.04.28 |