2013-08-16 1 views
11

I가 기본적으로 응용 프로그램에 필요한 모든 데이터를 반환하는 기준 :최대 절전 모드 기준 : 별개의 실체 다음 제한

Criteria criteria = session.createCriteria(Client.class); 
criteria.createAlias("address", "address"); 
criteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY); 
criteria.setFirstResult(init); 
criteria.setMaxResults(max); 
List<Client> clients = criteria.list(); 

문제는 관계 클라이언트/주소가 양방향이다 : 클라이언트가 하나 개의 주소를 가지고와 하나의 주소는 둘 이상의 클라이언트에 속할 수 있습니다.

테이블에 표시되는 클라이언트의 수에 따라 "단일"클라이언트 개체를 가져 오려고합니다.

먼저 setFirstResult/setMaxResults가 실행되기 때문에 이미 적용된 제한 내에서 클라이언트가 복제됩니다. (그룹화하지 않은 애플리케이션 레벨이 사용 된 후에) hibernate는 중복 클라이언트의 떼를 얻음으로 결국 setMaxResults에 지정된 최대 클라이언트보다 적은 클라이언트로 끝납니다.

클라이언트/주소에 필요한 모든 열을 반환하지 않으므로 (투영 그룹)별로 그룹화 할 수 없으며 쿼리가 그룹화하는 그룹 만 반환합니다.

(요약하면, My table은 페이지 당 100 개의 결과를가집니다. 그러나 중복을 제거한 후 100 대신에 98 개의 결과가 나타납니다.) 그 이유는 제한이 LIMIT 0,100이 적용되기 때문에 최대 절전 모드가 적용될 때입니다.)

답변

7

이 해결 :

criteria.setFetchMode("address.clients", FetchMode.SELECT); 

IT는 만들어 질 수있는 문제를 유발 가입 방지 할 수 있습니다.

물론 xml 구성 파일에서 fetch = "join"을 제거 할 수 있지만이 해결책은 빈을 검색 할 수있는 다른 장소에는 영향을주지 않습니다.

+0

FetchMode.SELECT이 문제를 해결했습니다. 다른 모드는이 경우 작동하지 않습니다. –

+0

FetchMode.SELECT는 훌륭합니다 ... 몇 가지 이유로 열심히 가져 오는 힘을 제외하고는. https://docs.jboss.org/hibernate/core/3.3/api/org/hibernate/FetchMode.html을 참조하십시오. 가져 오는 엔티티의 pk에서 "뚜렷한"작업을 수행하기 위해 최대 절전 모드를 수행 할 방법이 없습니까? ?? 이것은 가장 명백한 사소한 일인 것처럼 보이며, 평소와 같이 최대 절전 모드는 우리를 위해 삶을 극도로 복잡하게 만듭니다. – Marc

+0

그건 그렇고, HQL로이 작업을하는 것은 그 소리만큼이나 사소한 일입니다. 검색어에 "뚜렷한"이라는 단어를 추가하기 만하면됩니다. 이것이 Criteria API를 사용하는 것 자체가 너무 힘들다. 아직 OO 데이터베이스를 사용할 수 있습니까? – Marc

4

ID를 기반으로 클라이언트를 찾는 경우 다음과 같습니다. 조건에 따라 max 및 init 크기가 필요하지 않습니다. 왜냐하면 항상 하나의 클라이언트를 반환하기 때문입니다.

Criteria criteria = getSession().createCriteria(Client.class); 
criteria .add(Restrictions.eq("id", yourClientId); 
criteria.createAlias("address", "address"); 
criteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY); 
criteria.setFirstResult(init); 
criteria.setMaxResults(max); 
List<Client> clients = criteria.list(); 

id를 기반으로 주소를 찾는 경우 다음과 같습니다.

Criteria criteria = getSession().createCriteria(Client.class); 
criteria.createAlias("address", "address"); 
criteria .add(Restrictions.eq("address.id", yourAddressId); 
criteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY); 
criteria.setFirstResult(init); 
criteria.setMaxResults(max); 
List<Client> clients = criteria.list(); 
+3

답장을 보내 주셔서 감사합니다.하지만 모든 고객을 찾고 페이지의 응답으로 반환했습니다. 문제는 100 개의 결과를 반환하는 페이지보다 그룹화 한 후 반환되는 페이지가 더 적습니다 (DISTINCT_ROOT_ENTITY). 그 그룹화는 한계 이전에 일어나야합니다 ... – kandan

+0

두 번째 블록은 그의 질문에 @kandan이 게시 한 행 수가 적습니다. –

0

관계를 올바르게 이해하면 각 클라이언트 엔터티 클래스의 주소 및 주소에 클라이언트 목록이 표시됩니다. 당신은 단지 클라이언트의 목록을 원하는 경우 그래서 큰 문제는 무엇, 당신은 단지

Criteria criteria = session.createCriteria(Client.class); 
criteria.setFirstResult(init); 
criteria.setMaxResults(max); 
List<Client> clients = criteria.list(); 

가 왜 별명을 작성하고 distinct_root_entity를 사용하여 그들을 얻을 수없는 이유는 무엇입니까? 그 주소를 얻고 싶다면 DAO 나 ServiceImpl에서 접근 할 때, Hibernate는 어쨌든 그것을 당신을 위해 느리게 가져올 것이다.

내가 틀렸다고 정정하십시오. 이 "인 Ashish Thukral"다음 선으로 연결된 스레드에서 지적한 바와 같이

+0

감사. 나는 절전 모드로 강제로 별칭을 만들어서 쿼리에서 다른 데이터를 얻는다. 예를 들어 그들의 우편 번호 (필터가있는 페이지 매김 된 테이블)로 클라이언트를 필터링 할 수있다. 따라서 필요한 모든 데이터를 얻습니다. 주소가있는 클라이언트.문제는 그 주소가 또한 그 주소를 가지고있는 클라이언트의 집합이오고 나는 그들의 id에 의해 클라이언트를 통일하기 위해 resulttransformer를 필요로한다는 것이다. 아마도 어노테이션을 수정하지 않고도 클래스/테이블에 대한 특정 열을 검색/결합하지 말고 hibernate에게 기본 정의 된 (게으른 것인지 아닐지) 지 여부와 관계없이 다른 필드에 대해 수행 할 수 있습니다. – kandan

+1

나는 이것을 찾고 있다고 생각합니다. http://stackoverflow.com/questions/5567754/hibernate-criteria-n1-issue-with-maxresults?rq=1 –

+0

네, 고마워요. – kandan