我正在从javax迁移到jakkind. 我们的项目是用Spring Boot(从2.7升级到3.2)和Hibernate(5.6到6.3)构建的,我们使用PostgreSQL数据库(V14).一个trap 是自定义PostgreSQL方言的迁移,但我想我解决了令人满意的问题

当我们执行查询时,会出现主要问题:

      SELECT o FROM Order o
       WHERE (o.createdAt between :from and :to)
       AND (:query is null OR function('pgTextSearch', :query, o) = true)
       AND (:createdBy is null OR LOWER(o.createdBy) = LOWER(:createdBy))

它说:

Caused by: org.postgresql.util.PSQLException: ERROR: function lower(bytea) does not exist
Hinweis: No function matches the given name and argument types. You might need to add explicit type casts.

据我所知,这来自以‘NULL’作为参数的LOWER()函数的调用.:createdBy声明为字符串(分别为Varchar).在我的场景中:createdBy为空,但这应该被第一个OR条件截取.我遗漏了什么?

此外,我通过PostgreSQL-CLI执行了带有替换参数的查询,没有出现任何问题.

P.S. The query was modified for migration, but only within the custom function part.
P.P.S. I read the migration guides for spring boot and hibernate (SQM yikes!), but could not find any overlap to my use case.
P.P.P.S. I'm not setting the parameter by hand (e.g. .setParameter("createdBy", xyz)), the repository is a JpaRepository, thus parameter replacement is done by Spring Data

推荐答案

Short story

你打的是一只10多岁的虫子:

Long story

I.从V6开始,Hibernate确实有一个允许克服这些问题的API,例如:

    /**
     * Bind the given argument to a named query parameter using the given
     * Class reference to attempt to determine the {@link BindableType}
     * to use.  If unable to determine an appropriate {@link BindableType},
     * {@link #setParameter(String, Object)} is used.
     *
     * @see #setParameter(String, Object, BindableType)
     */
    <P> Query<R> setParameter(String parameter, P argument, Class<P> type);

不幸的是,你使用的是spring-data-jpa,Spring团队还没有采用Hibernate v6的新特性-在这里我建议提交相应的bug/cr.

二、特定查询的主要问题似乎有以下几点:

:createdBy参数在:createdBy is null OR LOWER(o.createdBy) = LOWER(:createdBy)子句中出现了两次,并且肯定没有从:createdBy is null表达式推断正确的SQL类型的选项,然而,从技术上讲,应该可以从LOWER(o.createdBy) = LOWER(:createdBy)表达式推断出varchar SQL类型,问题是Hibernate试图推断查询参数的SQL类型只有一次,所以你得到的是奇怪的bytea而不是varchar(这里我不知道为什么不将缺省设置为更常见的值而不是bytea).

你能试着把:createdBy is nullLOWER(o.createdBy) = LOWER(:createdBy)的表达式翻过来吗?我怀疑这可能会解决这个问题.

Iii.编写这种"通用"查询的惯用方式是使用SpEL或JPA规范,请判断Hibernate randomly throws error: Cannot coerce value [] [java.util.ArrayList] as Long

Postgresql相关问答推荐

转换失败:(—122.763091,49.04676)转换为地理(位置)""

在Postgres中,如何删除包含N个自然数的表,并替换为生成子查询?

将具有自定义类型的表从一种模式复制到另一种模式

PostGresql :正则表达式 Select 其中只有一个正斜杠的行

需要用 jack/pgx 更新 golang 中复合类型的 PSQL 行

如何在 psycopg2 中使用服务器端游标

如何从 WSL 连接到 windows postgres 数据库

使用 try/except 与 psycopg2 或with closing?

什么是 postgres 超级用户

从 PostgreSQL 中的字段中提取数字

如何在 psql 控制台中打印当前工作目录?

如何在 plpgsql 中使用记录类型变量?

如何禁用 postgresql缓存优化?

由于外键约束无法删除对象

Postgresql varchar 是否使用 unicode 字符长度或 ASCII 字符长度计算?

postgres - 比较两个数组

安装了 Postgres.app 但它不起作用

使用 Hibernate 注释映射 PostgreSQL 串行类型

PostgreSQL - 作为表名的动态值

pg_restore 目录错误