2012-01-06 4 views
2

왜 session.createCriteria (classtype) .list()가보다 많은 수의 개체를 반환합니까?왜 session.createCriteria (classtype) .list()가 목록에있는 것보다 많은 객체를 반환합니까?

반환 된 목록에 반복되는 개체가 임의의 순서로 포함되어 있습니다.

public Collection getAll() { 
     List list = null; 
     Session session = null; 
     Transaction tx = null; 
     try { 
      session = HibernateUtil.getSessionFactory().openSession(); 
      tx = session.beginTransaction(); 
      list = session.createCriteria(getClassType()).list(); 
      tx.commit(); 
     } catch (HibernateException ex) { 
      if (tx != null) { 
       tx.rollback(); 
      } 
      LOGGER.error("HibernateException in getAll"); 
     } finally { 
      if (session != null && session.isOpen()) { 
       session.close(); 
      } 
     } 
     return list; 
    } 
+0

를? 그런 다음 setMaxResults (10000)를 추가합니다. 1200 개의 다른 레코드 만 받았습니다. –

답변

2

귀하의 session.createCriteria(classtype).list() 호출이이 클래스의 일부 객체를 여러 번 반환한다고 가정합니다.

열심히 가져온 OneToMany 또는 ManyToMany 관계가있을 때 발생할 수 있습니다.

JB Nizet이 올바르게 지적한대로이 문제를 해결하는 한 가지 방법은 Criteria.DISTINCT_ROOT_ENTITYResultTransformer을 사용하는 것입니다.

그러나 이것은 '자바 측'에서 작업을 수행합니다. 모든 객체가 데이터베이스에서 가져와지고 모든 복제본이 제거됩니다.

열심히하는 대신 OneToMany 또는 ManyToMany을 게으르게 설정하는 것이 좋습니다 (기본값). 도움을

2

로드 된 엔티티에 가입을 사용하여 열정적으로 가져온 toMany 연결이 있기 때문일 수 있습니다.

criteria.setResultTransformer(DistinctRootEntityResultTransformer.INSTANCE); 

또는 순서가 중요하지 않은 경우 목록이 아닌 Set를 돌려 : 목록 만에 한 번 각 루트 개체를 얻을 수있는 별개의 루트 엔티티 결과 변압기를 사용합니다.

1

덕분에, 나는 그것을 사용하고, 이러한 방식으로 문제 해결 : 내가 기준으로는 setMaxResults()를 적용 할 수있는 방법이 경우

... 
try { 
      session = HibernateUtil.getSessionFactory().openSession(); 
      tx = session.beginTransaction(); 
      Criteria criteria = session.createCriteria(getClassType()) 
       .setProjection(Projections.id()) 
       .setFirstResult(getStart()) 
       .setMaxResults(getLength());  
      HashSet<Long> ids = new HashSet(criteria.list());    

      criteria = session.createCriteria(getClassType()) 
       .add(Restrictions.in(ID_COLUMN_NAME, ids)) 
      TreeSet<Employee> items = new TreeSet(criteria.list()); 

      list = new ArrayList<Employee>(items); 

      tx.commit(); 
     } catch (HibernateException ex) { 
... 
관련 문제