2012-01-06 8 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のリレーションを熱心に取得した場合に発生します。

これを解決する1つの方法は、JB Nizetが正しく指摘しているとおり、Criteria.DISTINCT_ROOT_ENTITYResultTransformerを使用することです。

しかし、これは「java側」で作業を行います。すべてのオブジェクトがデータベースからフェッチされ、すべての重複が削除されます。

eagerの代わりに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) { 
...