Hibernate(JPA) 열성적인 쿼리를 수행하고 모든 하위 객체를 로드하는 방법

StackOverflow https://stackoverflow.com/questions/70992

  •  09-06-2019
  •  | 
  •  

문제

내 관련 이전 질문, 데이터에 액세스해야 할 수 있는 스레드가 여러 개 있으므로 모든 하위 개체가 로드되었는지 확인하고 싶습니다(따라서 지연 로딩 예외를 방지함).나는 이를 수행하는 방법이 쿼리(EJB QL)에서 "fetch" 키워드를 사용하는 것임을 이해합니다.이와 같이:

select distinct o from Order o left join fetch o.orderLines

다음을 갖는 모델을 가정합니다. Order 세트가 있는 클래스 OrderLines 그 안에.

내 질문은 "고유한" 키워드가 필요한 것 같다는 것입니다. 그렇지 않으면 나는 Order 각각 OrderLine.내가 옳은 일을 하고 있는 걸까?

아마도 더 중요한 것은, 아무리 깊이에 관계없이 모든 하위 개체를 끌어올 수 있는 방법이 있습니까?우리는 약 10-15개의 클래스를 가지고 있으며 서버를 위해서는 모든 것을 로드해야 합니다...나는 사용을 피하고 있었다 FetchType.EAGER 이는 항상 열정적이며 특히 웹 프런트 엔드가 모든 것을 로드한다는 것을 의미합니다. 그러나 아마도 그것이 갈 길일 것입니다. 그것이 당신이 하는 일입니까?이전에 이 방법을 시도한 후 웹페이지 속도가 매우 느려졌던 것으로 기억됩니다. 하지만 이는 아마도 두 번째 수준 캐시를 사용해야 한다는 의미일까요?

도움이 되었습니까?

해결책

주석을 변경하는 것은 나쁜 생각입니다.런타임에 게으른 상태로 변경할 수 없기 때문입니다.모든 것을 게으르게 만들고 필요에 따라 가져오는 것이 더 좋습니다.

매핑 없이는 문제를 이해할 수 없습니다.설명하는 사용 사례에 필요한 것은 Left Join Fetch뿐입니다.물론 orderline에 상위 주문이 있는 경우 모든 orderline에 대한 주문을 다시 받게 됩니다.

다른 팁

EJBQL에서 fetch 키워드를 사용하는 것이 확실하지 않습니다. 주석과 혼동을 일으킬 수 있습니다.

관계 속성에 FetchType 속성을 추가해 보셨나요?

@OneToMany(fetch=FetchType.EAGER)?

보다:

http://java.sun.com/javaee/5/docs/api/javax/persistence/FetchType.html http://www.jroller.com/eyallupu/entry/hibernate_Exception_simultaneously_fetch_multiple

결과 변환기를 사용해 보셨나요?기준 쿼리를 사용하는 경우 결과 변환기를 적용할 수 있습니다(비록 페이지 매김 및 결과 변환기에 몇 가지 문제가 있습니다.):

Criteria c = ((Session)em.getDelegate()).createCriteria(Order.class);
c.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);
c.list();

그만큼 em.getDelegate() 최대 절전 모드를 사용하는 경우에만 작동하는 해킹입니다.

아마도 더 중요한 것은 아무리 깊더라도 모든 어린이 물체를 끌어낼 수있는 방법이 있습니까?우리는 약 10-15 개의 클래스를 가지고 있으며 서버의 경우 모든 것을로드해야합니다 ...나는 fetchtype.ager를 사용하는 것을 피하고 있었기 때문에 항상 열망하고 특히 웹 프론트 엔드가 모든 것을로드한다는 것을 의미했지만 아마도 그 길이 - 당신이하는 일입니까?나는 우리가 전에 이것을 시도한 다음 정말로 느리게 웹 페이지를 얻는 것을 기억하는 것 같습니다. 그러나 아마도 우리는 두 번째 레벨 캐시를 사용해야한다는 것을 의미할까요?

여전히 관심이 있으시면 이 스레드에서 비슷한 질문에 답변했습니다. 최대 절전 모드 컬렉션을 직렬화하는 방법.

기본적으로 다음과 같은 유틸리티를 사용합니다. 도저 이는 빈을 다른 빈에 매핑하고 이를 통해 모든 게으른 로드를 트리거합니다.상상할 수 있듯이 모든 컬렉션을 적극적으로 가져오는 경우 이 방법이 더 잘 작동합니다.

(분리된) 기준 쿼리를 사용하고 가져오기 모드를 설정하여 이와 같은 작업을 수행할 수 있습니다.예:

Session s = ((HibernateEntityManager) em).getSession().getSessionFactory().openSession();
DetachedCriteria dc = DetachedCriteria.forClass(MyEntity.class).add(Expression.idEq(id));
dc.setFetchMode("innerTable", FetchMode.JOIN);
Criteria c = dc.getExecutableCriteria(s);
MyEntity a = (MyEntity)c.uniqueResult();

이는 ManyToOne 관계에서만 작동하며 @ManyToOne(fetch=FetchType.EAGER) 이 적절할 것입니다.

하나 이상의 OneToMany 관계를 열심히 가져오는 것은 권장되지 않으며 Jeremy가 게시한 링크에서 읽을 수 있듯이 작동하지 않습니다.그러한 가져오기를 수행하는 데 필요한 SQL 문에 대해 생각해 보십시오.

내가 한 일은 개체 관리자에 대한 개체 맵을 유지하도록 코드를 리팩터링하고 새로 고쳐야 할 때마다 개체에 대한 이전 개체 관리자를 닫고 새 개체 관리자를 여는 것입니다.나는 위의 쿼리를 사용하지 않고 사용했습니다. 술책 내 필요에 비해 너무 깊어지기 때문에 - 일반 조인을 수행하면 OrderLines가 당겨집니다. 술책 더욱 깊어지게 만듭니다.

이 작업이 필요한 개체는 약 20개뿐입니다. 따라서 20개의 열린 엔터티 관리자를 갖는 데 따른 리소스 오버헤드는 문제가 되지 않는다고 생각합니다. 하지만 이것이 실행될 때 DBA는 다른 견해를 가질 수 있습니다.

또한 DB 작업이 메인 스레드에 있고 엔터티 관리자가 있도록 재작업했습니다.

크리스

문제가 LazyInitializationExceptions인 경우 OpenSessionInViewFilter를 추가하여 이를 방지할 수 있습니다.
이렇게 하면 객체가 뷰에 로드될 수 있지만 속도 문제에는 도움이 되지 않습니다.

     <filter>
        <filter-name>hibernateFilter</filter-name>
        <filter-class> org.springframework.orm.hibernate3.support.OpenSessionInViewFilter
        </filter-class>
    </filter>
    <filter-mapping>
        <filter-name>hibernateFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top