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

JPA自定义JPQL查询中LOWER函数类型不匹配问题求助

问题:JPQL使用LOWER函数时出现类型不匹配错误

我在JPA Repository类中用JPQL编写了自定义查询,需求是当documentText列包含指定:text参数时,返回DocumentDTO类型的列表,因此对字段和参数都做了小写转换操作。

原代码如下:

@Query("SELECT new com.hakstudio.archiveapp.dto.DocumentDTO" +
        "(id, name, accessAuth, uploadedDate, uploadedBy, uploadedByTc, editedBy, editedByTc) " +
        "FROM Document " +
        "WHERE LOWER(documentText) LIKE CONCAT('%', LOWER(:text), '%')")
List<DocumentDTO> findByDocument(@Param("text") String text);

执行时出现错误:

org.hibernate.QueryException: Parameter 1 of function lower() has type STRING, but argument is of type java.lang.String

我尝试给字段和参数添加as string转换,但没有效果:

@Query("SELECT new com.hakstudio.archiveapp.dto.DocumentDTO" +
        "(id, name, accessAuth, uploadedDate, uploadedBy, uploadedByTc, editedBy, editedByTc) " +
        "FROM Document " +
        "WHERE LOWER(documentText as string) LIKE CONCAT('%'," +
        "LOWER(:text as string)" +
        ",'%')")
List<DocumentDTO> findByDocument(@Param("text") String text);

解决方案

这个错误是Hibernate在处理JPQL参数类型映射时的小问题,无需手动转换java.lang.String到JPQL的STRING类型,以下几种方法可以解决:

方法1:在Java层提前处理参数小写

在调用查询前将参数转换为小写,JPQL中只处理数据库字段的小写:

// Repository层代码
@Query("SELECT new com.hakstudio.archiveapp.dto.DocumentDTO(id, name, accessAuth, uploadedDate, uploadedBy, uploadedByTc, editedBy, editedByTc) " +
        "FROM Document " +
        "WHERE LOWER(documentText) LIKE CONCAT('%', :text, '%')")
List<DocumentDTO> findByDocument(@Param("text") String text);

// 调用时传入小写后的参数
documentRepository.findByDocument(text.toLowerCase());

方法2:将通配符拼接移到Java层

直接在Java层拼接%通配符,简化JPQL语句:

// Repository层代码
@Query("SELECT new com.hakstudio.archiveapp.dto.DocumentDTO(id, name, accessAuth, uploadedDate, uploadedBy, uploadedByTc, editedBy, editedByTc) " +
        "FROM Document " +
        "WHERE LOWER(documentText) LIKE :text")
List<DocumentDTO> findByDocument(@Param("text") String text);

// 调用时拼接通配符并转小写
documentRepository.findByDocument("%" + text.toLowerCase() + "%");

方法3:使用CAST函数显式转换(针对部分Hibernate版本)

如果前两种方法无效,可以尝试用JPQL的CAST函数显式转换参数类型:

@Query("SELECT new com.hakstudio.archiveapp.dto.DocumentDTO(id, name, accessAuth, uploadedDate, uploadedBy, uploadedByTc, editedBy, editedByTc) " +
        "FROM Document " +
        "WHERE LOWER(documentText) LIKE CONCAT('%', LOWER(CAST(:text AS string)), '%')")
List<DocumentDTO> findByDocument(@Param("text") String text);

解释:错误提示中的STRING是JPQL定义的类型,java.lang.String是Java类型,正常情况下Hibernate会自动完成映射,出现该问题大概率是参数绑定的语法细节或特定Hibernate版本的小bug,上述方法都能解决该问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 00:56:22