[하이버네이트 3.5] Fetch Profile
참조: http://blog.frankel.ch/hibernate-hard-facts-part-6
기본으로 Xxx-To-Many 관계에서 Many 쪽 연관에 별다른 설정을 하지 않으면 lazy loading이 적요됩니다. 즉..
[java]
class Member {
private Set<Role>;
roles;
…
}
[/java]
이런 코드가 있을 때 만약 하이버네이트로 Member를 읽어오면 Member의 Roles까지 읽어오진 않습니다. 그러다 세션이 열려있는 상태에서 getRoles()를 호출하는 등으로 필요해지는 순간이 오면 그때 DB에 쿼리를 보내서 가져오게 되죠. 이렇게 필요해지면 가져오는걸 lazy loading이라고 하고 이렇게 하는 이유는 굳이 당장 필요없는 객체로 메모리를 잡아먹을 필요도 없기 때문입니다.
그런데 Roles를 Member 객체를 가져온 뒤에 자주 참조한다면 애초에 Member를 가져올 때 미리 가져다 놓고 캐싱을 해버리는게 더 좋습니다. 그럴때 사용하는 기능이 하이버네이트의 Fetch라는 것인데 FetchMode라고 해서 도메인 클래스에 애노테이션으로 또는 XML로 매핑을 할 때 이 모드를 설정해 둘 수 있습니다. LAZY는 위에서 설명했고 EAGER가 바로 LAZY와는 반대로 Member를 가져갈때 Roles도 전부 가져가라는 뜻이 됩니다.
그런데 이런 설정을 매핑에서만 설정할 수 있는게 아니라 Criteria나 HQL을 만들 때도 설정할 수 있죠. Critera.setFatchMode()를 사용하거나 FETCH JOIN이라는 HQL을 사용하면 됩니다. 그런데.. 매번 쿼리를 만들 때마다 이렇게 FetchMode를 설정하는게 귀찮을 수 있으니 하이버네이트 3.5에서는 미리 특정 관계에 대한 FetchMode를 정의해 놓고(펫치 프로파일) 쿼리를 만들 시점에 해당 그 팻치 프로파일을 가져다 쓸 수 있는 기능을 제공합니다.
[java]
@Entity
@FetchProfile(name = "customer-with-orders", fetchOverrides = {
@FetchProfile.FetchOverride(entity = Customer.class, association = "orders", mode = FetchMode.JOIN)
})
public class Customer {
@Id
@GeneratedValue
private long id;
private String name;
private long customerNumber;
@OneToMany
private Set<Order> orders;
// standard getter/setter
...
}
[/java]
from: http://docs.jboss.org/hibernate/stable/annotations/reference/en/html_single/#d0e3524
이렇게 orders는 기본으로 lazy loading이 적용되서 사실상 FetchMode=Lazy로 설정한 것과 동일하지만.. 쿼리를 만들 때 @FetchProfile에 정의한 걸 적용해서 마치 Eager로 설정한 것처럼 orders를 미리 읽어가는 쿼리를 만들 수도 있습니다.
[java]
Session session = ...;
session.enableFetchProfile( "customer-with-orders" ); // name matches @FetchProfile name
Customer customer = (Customer) session.get( Customer.class, customerId );
session.disableFetchProfile( "customer-with-orders" ); // or just close the session
...
[/java]
from: http://docs.jboss.org/hibernate/stable/annotations/reference/en/html_single/#d0e3524
흠.. 이걸 처음 보고. 어차피 fetchMode 설정하는게도 한줄 필요하고 저기서도 fetch profile 때문에 한줄 필요하면 똑같은거 아닌가 생각했지만 fetchMode를 조정할 곳이 한군대로 축소된다는 장점이 있더군요. 여러군데에서 fetchMode를 조작하는 코드가 있다면 fetch profile을 써먹으면 괜찮겠네요.