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

Spring Boot3升级QueryDSL5.0.0后Enum查询SQL语法报错

Spring Boot 3.x + QueryDSL 5.0.0 升级后 select 中条件表达式导致 MySQL 语法错误

问题根源

从错误日志能看到,QueryDSL 生成的 SQL 把 product.stockStatus.eq(StockStatus.AVAILABLE) 直接转换为 p1_0.stockStatus=cast(? as smallint) 并放到了 select 列列表里。MySQL 不支持这种直接将比较表达式作为查询列的写法,这就是语法错误的核心原因。旧版本 QueryDSL/Spring Boot 可能隐式做了兼容处理,但升级到 5.x/3.x 后这个逻辑被调整了。

解决方案

需要把这个条件表达式转换成 MySQL 能识别的合法列表达式,推荐两种实现方式:

方案1:使用 Case 表达式(直观易读)

public List<ProductMiniResource> getAllProductsByProductCode(String[] productCodes) {
    return from(product)
            .where(product.code.in(productCodes)
                    .and(product.status.eq(ProductStatus.ACTIVE)))
            .select(new QProductMiniResource(product.id,
                    product.code,
                    product.name,
                    product.logoPath,
                    // 用case表达式生成合法的布尔值列
                    Expressions.cases()
                        .when(product.stockStatus.eq(StockStatus.AVAILABLE)).then(true)
                        .otherwise(false),
                    product.productRedirectUrl,
                    product.displayName,
                    product.inquiryType,
                    product.allowReminder,
                    product.allowSchedulePayment,
                    product.allowSavePayment))
            .fetch();
}

方案2:使用 booleanTemplate 直接定义 SQL 片段

public List<ProductMiniResource> getAllProductsByProductCode(String[] productCodes) {
    return from(product)
            .where(product.code.in(productCodes)
                    .and(product.status.eq(ProductStatus.ACTIVE)))
            .select(new QProductMiniResource(product.id,
                    product.code,
                    product.name,
                    product.logoPath,
                    // 直接指定MySQL支持的表达式格式
                    Expressions.booleanTemplate("{0} = {1}", product.stockStatus, StockStatus.AVAILABLE),
                    product.productRedirectUrl,
                    product.displayName,
                    product.inquiryType,
                    product.allowReminder,
                    product.allowSchedulePayment,
                    product.allowSavePayment))
            .fetch();
}

说明

两种方案都会生成 MySQL 可识别的合法 SQL:Case 表达式会被转换为 case when p1_0.stock_status = ? then 1 else 0 end,booleanTemplate 则直接生成等价的合法比较表达式,最终都能正确返回布尔值对应的结果。

内容的提问来源于stack exchange,提问作者Milan Paudyal

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 00:53:09