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

Spring Boot 3迁移后遇重复SQL别名[COL_SK]错误求助

Spring Boot 3.x(Hibernate 6.1.7)迁移后JPQL查询报重复别名错误的解决

问题场景

从Spring Boot 2.x迁移到3.x(搭配Hibernate 6.1.7)后,原有JPQL查询代码抛出以下错误:

org.springframework.orm.jpa.JpaSystemException: Encountered a duplicated sql alias [COL_SK] during auto-discovery of a native-sql query

关联代码如下:
实体类ID字段定义:

@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator="SEQ1")
@SequenceGenerator(name="SEQ1", sequenceName="SEQ1", allocationSize=1)
@Column(name = "COL_SK")
private Long sk;

Service层查询实现:

@PersistenceContext
private EntityManager entityManager;

private static final String CCN_LIST = "select c1 FROM CCN c1 where c1.ccnCode in (:ccnCdList)";

@Override
public List<CCN> findByCcnCdList(List<String> ccnCdList) {
    List<CCN> ccns = new ArrayList<CCN>();
    
    if (CollectionUtils.isNotEmpty(ccnCdList)) {
        List<List<String>> ccnCdSubLists = ListUtils.partition(ccnCdList, 2000);

        Query query = entityManager.createQuery(CCN_LIST, CCN.class);
                            
        for (List<String> ccnCdSubList : ccnCdSubLists) {               
            query.setParameter("ccnCdList", ccnCdSubList);
            ccns.addAll(query.getResultList());                             
        }           
    }
    
    return ccns;
}

上述代码在Spring Boot 2.x环境下可正常运行。

问题原因

Hibernate 6对Query实例的状态管理机制做了调整,复用同一个Query实例多次执行查询时,内部SQL生成逻辑会重复绑定实体字段的别名,进而触发COL_SK别名重复的冲突。而Spring Boot 2.x默认使用的Hibernate 5.x对这种复用场景兼容性更强,不会出现该问题。

解决方案

取消Query实例的复用,将Query的创建逻辑移至循环内部,每次子查询都生成新的Query对象:

修改后的Service代码:

@PersistenceContext
private EntityManager entityManager;

private static final String CCN_LIST = "select c1 FROM CCN c1 where c1.ccnCode in (:ccnCdList)";

@Override
public List<CCN> findByCcnCdList(List<String> ccnCdList) {
    List<CCN> ccns = new ArrayList<CCN>();
    
    if (CollectionUtils.isNotEmpty(ccnCdList)) {
        List<List<String>> ccnCdSubLists = ListUtils.partition(ccnCdList, 2000);

        for (List<String> ccnCdSubList : ccnCdSubLists) {               
            // 每次循环创建新的Query实例
            Query query = entityManager.createQuery(CCN_LIST, CCN.class);
            query.setParameter("ccnCdList", ccnCdSubList);
            ccns.addAll(query.getResultList());                             
        }           
    }
    
    return ccns;
}

补充说明

若坚持要复用Query实例,可尝试在每次执行后调用query.unwrap(JpaQuery.class).clearParameters()清除参数,但这种方式可靠性不如重新创建Query实例——因为Hibernate 6的Query内部包含更多不可完全重置的元数据信息。

内容的提问来源于stack exchange,提问作者Vikram R

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 01:48:27