You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

迁移到Hibernate 6与QueryDSL后.transform()方法报错的解决方法

Hibernate 6.5.3.Final + QueryDSL 5.1.0 下.transform()方法报错解决办法

问题场景

项目迁移至Hibernate 6.5.3.Final + QueryDSL 5.1.0后,调用QueryDSL的.transform()方法时触发NoSuchMethodError异常,核心错误为java.lang.NoSuchMethodError: 'java.lang.Object org.hibernate.ScrollableResults.get(int)'。

相关代码

初始化类代码

public class Test{
    private final EntityPath<SomeEntity> path;
    private final Querydsl querydsl;

    public Test(EntityManager entityManager) {
        this.path = SimpleEntityPathResolver.INSTANCE.createPath(SomeEntity.class);
        querydsl = new Querydsl(entityManager, new PathBuilder<SomeEntity>(this.path.getType(), this.path.getMetadata()));
    }
}

业务方法代码

private Page<SomeObject> findAllSomeObject(JPQLQuery<?> query, Pageable pageable) {

    List<SomeObject> result = query
            .select(someExpression)
            .transform(GroupBy.groupBy(id)
                    .list(Projections.constructor(SomeObject.class, someExpression))
            );

    return PageableExecutionUtils.getPage(result, pageable, () -> totalCount);
}

异常堆栈核心信息

2025-03-27 21:32:23 [http-nio-auto-1-exec-3] ERROR o.a.c.c.C.[.[.[.[dispatcherServlet] - Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed: java.lang.RuntimeException: java.lang.NoSuchMethodError: 'java.lang.Object org.hibernate.ScrollableResults.get(int)'] with root cause
java.lang.NoSuchMethodError: 'java.lang.Object org.hibernate.ScrollableResults.get(int)'
    at com.querydsl.jpa.ScrollableResultsIterator.next(ScrollableResultsIterator.java:70)
    at com.querydsl.core.group.GroupByList.transform(GroupByList.java:60)
    at com.querydsl.core.group.GroupByList.transform(GroupByList.java:36)
    at com.querydsl.core.support.FetchableQueryBase.transform(FetchableQueryBase.java:55)
    ...(省略中间堆栈内容)
    at java.base/java.lang.Thread.run(Thread.java:833)

解决方案

该错误本质是Hibernate 6重构了ScrollableResults接口:原get(int)方法被移除,替换为带泛型参数的get(int, Class<T>)或无参get()方法,但QueryDSL 5.1.0的JPA模块未适配这一变更。可通过以下方式解决:

  1. 升级QueryDSL版本
    QueryDSL从5.2.0版本开始正式适配Hibernate 6的API变更,直接将QueryDSL依赖升级到5.2.0及以上的稳定版本,即可解决方法调用不兼容问题。

  2. 手动实现分组逻辑(临时方案)
    若暂时无法升级QueryDSL,可绕过GroupBy.transform(),用Java Stream API手动实现分组:

    private Page<SomeObject> findAllSomeObject(JPQLQuery<?> query, Pageable pageable) {
        // 获取原始查询结果
        List<Tuple> rawResults = query.select(id, someExpression).fetch();
        // 手动分组并构造目标对象
        List<SomeObject> result = rawResults.stream()
                .collect(Collectors.groupingBy(tuple -> tuple.get(id)))
                .values().stream()
                .map(group -> group.stream()
                        .findFirst()
                        .map(t -> new SomeObject(t.get(someExpression)))
                        .orElse(null))
                .filter(Objects::nonNull)
                .collect(Collectors.toList());
    
        return PageableExecutionUtils.getPage(result, pageable, () -> totalCount);
    }
    

    注:需根据实际表达式和对象构造逻辑调整代码。

  3. 排查依赖冲突
    使用mvn dependency:tree(Maven)或./gradlew dependencies(Gradle)检查项目依赖树,排除混入的低版本Hibernate或QueryDSL依赖,确保依赖版本统一。


内容的提问来源于stack exchange,提问作者Mike Sonarov

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 18:17:31