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

H2自定义函数可在WHERE子句使用但SELECT子句访问失败问题排查

问题产生原因

  1. 默认@Query注解的内容是JPQL语句而非原生SQL,JPQL解析校验阶段只会识别标准语法和内置函数,你自定义的H2函数ANOTHERTEST返回自定义User实体类型,JPQL无法识别该返回类型的实体映射规则,直接触发查询校验失败异常。
  2. repoFunction1能正常运行的原因是TEST函数返回Integer基础类型,JPQL支持基础类型的等值比较逻辑,不会触发校验失败。
  3. 即便你改用原生SQL,直接给自定义函数传u(整条实体记录)的写法也不符合SQL语法规则,SQL层面只能传递表的具体字段值,无法直接将整条行记录作为Java实体参数传入自定义函数。
  4. 你尝试将schema.sql重命名为import.sql没有效果,是因为该问题和SQL脚本的初始化执行时机无关,属于查询写法和自定义函数的使用错误。

解决方法

1. 调整自定义函数入参

修改CustomH2类的customAnotherTestFunction方法,改为接收具体字段值,手动构造User对象返回:

package com.example.demospringbootproject.h2;
import com.example.demospringbootproject.model.User;

public class CustomH2 {

    public static Integer customTestFunction(Integer id){
        return id;
    }
    // 调整此处入参为具体的id、name字段
    public static User customAnotherTestFunction(Integer id, String name){
        User user = new User();
        user.setId(id);
        user.setName(name);
        return user;
    }
}

2. 调整Repository查询写法

修改repoFunction2的@Query注解,开启原生查询,传递具体字段值到自定义函数:

// 开启nativeQuery = true 走原生SQL逻辑,表名用schema中定义的小写user
@Query(value = "Select ANOTHERTEST(u.id, u.name) From user u where u.id = 1", nativeQuery = true)
User repoFunction2();

如果调整后仍出现结果映射问题,可以给返回结果添加SqlResultSetMapping注解配置自定义实体的映射规则,简单场景下以上两步修改即可正常运行。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 04:24:08