PostgreSQL function used in QueryDSL is not working, returns ERROR: syntax error at or near "."

PostgreSQL function used in QueryDSL is not working, returns ERROR: syntax error at or near "."

这是我关于 Whosebug 的第一个问题,如果有任何不准确之处,请提前致歉

在我的项目中,我使用 Hibernate(作为 ORM 框架)和 QueryDSL 库,PostgreSQL 作为数据库。

基本上,我需要检查列表 'arr' 的大小,它是一些 'X' class 的 属性,所以我搜索并找到了一种方法如下使用带有 querydsl 的 postgres 函数(在你问之前,我 不能按要求使用本机查询 ):

BooleanBuilder builder = new BooleanBuilder();

builder.and(Expressions.booleanTemplate("function('array_length', {0})", qX.arr)
                .castToNum(Integer.class).gt(0));

编译一切正常,但是当调用存储库方法时,出现错误:

ERROR: syntax error at or near "." Position: ...

我检查了所有内容,但没有“.”。在那个位置和附近的位置也是如此。 但是设置spring.jpa.show-sql=true后发现确实有一个“.”。该位置某处的符号,结果 SQL 语句如下所示:

... and cast(array_length(.) as int4)>?

这意味着,JPA 无法将我的 'arr' 放入 array_length() 函数中(是这样吗?)

为什么会这样?难道我做错了什么? 提前谢谢你

我的实体 class 看起来像这样:

    @EqualsAndHashCode(callSuper = true)
    @Entity
    @Table
    @Data
    @NoArgsConstructor
    @TypeDefs({
            @TypeDef(name = "list-array", typeClass = ListArrayType.class)
    })
    public class X extends BaseClass {
    
        // private fields
    
        @Type(type = "list-array")
        @Column(name = "arr", columnDefinition = "bigint[]")
        @ElementCollection
        @OrderColumn
        private List<Long> arr;
    }

我试过不使用@ElementCollection 和@OrderColumn 注释,但这给了我转换错误

@ElementCollection@OrderColumn 在这里引起了第一个问题。删除它们(并且架构设置正确)后,需要更正函数调用(SQL 模板)。


@ElementCollection@OrderColumn 的问题在于它们代表了另一种将 lists/arrays 作为实体的一部分存储的方法。
@ElementCollection 将元素存储在单独的 table 中,每个元素都在单独的行中(每个元素都引用实体)。为了“记住”正确的顺序,需要一个 @OrderColumn 作为单独的 table 的一部分,因为如果没有指定顺序,行将以任意顺序返回 ()。

相比之下,ListArrayType@Column(columnDefinition = "bigint[]") 将启用在 实体行的一列 中保存元素序列。因此,没有使用单独的 table,并且由于元素没有保存在单独的行中,因此不需要额外的订单信息。

所以 没有 @ElementCollection@OrderColumn 列表映射已经正确设置。请注意,您的架构当前可能处于错误状态,并且您需要确保实体 table 中有一个 bigint[] 列(例如,可以在 [=10 时由休眠自动创建) =] 和 @OrderColumn 被删除)。


2. 修复 PostgresQL 函数调用:array_length 需要第二个参数指示返回长度的数组维度(https://www.postgresql.org/docs/current/functions-array.html ).因此,按如下方式指定模板字符串应该会得到正确的结果:
"function('array_length', {0}, 1)"
(“1”是请求的数组维度)。