【问题标题】:How to use ScrollableResults for Hibernate Queries when joining many different entities加入许多不同实体时如何使用 ScrollableResults 进行休眠查询
【发布时间】:2021-02-17 12:20:46
【问题描述】:

我正在使用 Spring Boot 端点从数据库查询中返回结果。在 TypedQuery 上使用 getResultList() 时效果很好。但是我知道我将不得不管理非常大的数据集。我正在研究通过休眠使用 ScrollableResults,但我无法弄清楚如何实际引用每一行的内容。

StatelessSession session = ((Session) entityManager.getDelegate()).getSessionFactory().openStatelessSession();

    criteriaQuery.multiselect(selections);

    criteriaQuery.where(predicates.toArray(new Predicate[]{}));

    Query<?> query = session.createQuery(criteriaQuery);
    query.setMaxResults(5);
    query.setFetchSize(1000);
    query.setReadOnly(true);
    ScrollableResults results = query.scroll(ScrollMode.FORWARD_ONLY);

    while(results.next()){
        Object row = results.get();
    }
    results.close();
    session.close();

我已经尝试过 results.get(0)、results.get(0)[0]、results.getLong(0)、Object[] row vs Object row 等。选项。我所做的没有什么比 java 对象引用更多的了。我也尝试过投射并得到“无法投射错误”。有时我得到一个错误,“查询指定一个持有者类”。不确定这意味着什么,因为我的条件查询是通过加入 1 个或多个实体而构建的,其中实体和选定的列事先不知道。所以我实际上并没有指定一个类。它们的实体和选择由用户输入指定。有什么想法吗?谢谢!

更新: 我可以做 System.out.println(scroll.getType(0));在这种情况下观察很长时间。 但是当我尝试保存那么长的 (.getLong(0)) 时,我得到了错误,“查询指定了一个持有者类”。或者再次出现无法投射错误。

【问题讨论】:

    标签: java hibernate criteriaquery scrollableresults


    【解决方案1】:

    想通了。 queryDetails 是CriteriaQuery&lt;Tuple&gt;

    StatelessSession session = entityManagers.get("DatasourceName").unwrap(Session.class).getSessionFactory().openStatelessSession();
            
        
    
    Stream<Tuple> resultStream = session.createQuery(queryDetails)
                    .setReadOnly(true)
                    .setMaxResults(100)
                    .setFetchSize(1000)
                    .setCacheable(false)
                    .getResultStream();
            Iterator<Tuple> itr = resultStream.iterator();
    while (itr.hasNext()){
                    //Get the next row:
                    Tuple row = itr.next();
    
    }
    

    【讨论】:

      【解决方案2】:

      使用 multiselectCriteriaQuery 会生成 Object[] 或 javax.persistence.Tuple 作为结果类型。也许您应该尝试调试以查看实际的对象类型,然后您可以进一步工作。

      如果您要处理并返回所有行,则无需使用ScrollableResults API,因为无论如何您都必须为所有行创建对象。如果您的用例是进行某种聚合,我建议您改用聚合函数并让数据库进行聚合。

      【讨论】:

        猜你喜欢
        • 2015-08-11
        • 2013-03-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-12-19
        • 1970-01-01
        相关资源
        最近更新 更多