为什么session.createCriteria(classtype).list()返回的对象多于列表中的对象?

时间:2012-01-06 13:15:01

标签: java hibernate criteria

为什么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;
    }

3 个答案:

答案 0 :(得分:2)

这可能是因为加载的实体具有使用连接急切获取的toMany关联。使用不同的根实体结果转换器仅在列表中获取一次根实体:

criteria.setResultTransformer(DistinctRootEntityResultTransformer.INSTANCE);

如果订单不重要,则返回Set而不是List。

答案 1 :(得分:2)

我假设您的session.createCriteria(classtype).list()调用多次返回此类的某些对象。

当您急切地获取OneToManyManyToMany关系时,可能会发生这种情况。

正如JB Nizet正确指出的那样,解决此问题的一种方法是使用Criteria.DISTINCT_ROOT_ENTITY ResultTransformer

然而,这将在'java side'进行工作:将从数据库中提取所有对象,然后删除所有重复项。

最好使OneToManyManyToMany懒惰(这是默认值)而不是急切。

答案 2 :(得分:1)

感谢您的帮助,我使用它,并以这种方式解决问题:

...
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) {
...