Criteria JPA - 调用 Postgres CAST 函数

问题描述 投票:0回答:2

我尝试使用 Criteria 调用 Postgres 函数,但它不起作用。我需要在 UUID 字段中使用

LIKE
子句,因此我需要先转换为
VARCHAR

我需要的结果:

SELECT * FROM my_table WHERE cast(uuid as varchar(36)) like '%1234%';

我在标准中做什么:

final Path<UUID> uuidField = from.get("uuid");
var cast = cb.function("cast", String.class, uuidField, cb.literal("as varchar(36)"));
cb.like(cast, String.format("%%%s%%", stringValue));

正在生成的查询:

HQL: select generatedAlias0 from com.MyTable as generatedAlias0 where function('cast', generatedAlias0.uuid, 'as varchar(36)') like '%1234%' order by generatedAlias0.name asc

错误:

2022-08-08 18:38:48,549 WARN  [io.ver.cor.imp.BlockedThreadChecker] (vertx-blocked-thread-checker) Thread Thread[vert.x-eventloop-thread-9,5,main] has been blocked for 2393 ms, time limit is 2000 ms: io.vertx.core.VertxException: Thread blocked
    at antlr.ASTFactory.make(ASTFactory.java:342)
    at antlr.ASTFactory.make(ASTFactory.java:352)
    at org.hibernate.hql.internal.antlr.HqlBaseParser.jpaFunctionSyntax(HqlBaseParser.java:4633)
    at org.hibernate.hql.internal.antlr.HqlBaseParser.primaryExpression(HqlBaseParser.java:1075)

日志不太清楚(我使用的是 Quarkus + Hibernate Reactive),但我怀疑它在数据库中崩溃了,因为

function('cast', generatedAlias0.uuid, 'as varchar(36)')

我认为应该是这样的:

function('cast', generatedAlias0.uuid, as varchar(36))
(不带引号)。但我不知道如何获得这个结果来检验我的理论。

如何调用这个

CAST
函数?

java postgresql jpa criteria
2个回答
1
投票

在研究了一些可能的解决方案(我避免创建自定义数据库例程)之后,我在另一个问题的答案中发现了一些有趣的东西:

目前JPA没有replace()和cast(string as numeric)的API。但如果数据库可移植性不重要,您可以使用 CriteriaBuilder.function(...) 创建数据库本机函数。

来源:JPA 标准生成器:如何按顺序替换字符串并将其转换为数字?

我不知道这是否记录在某个地方,但假设无法使用 Criteria 调用

CAST(x AS y)
,我尝试了一种解决方法来强制
UUID
VARCHAR
转换,而不使用可能不受支持的
 CAST
功能。

我测试了对数据库的直接 SQL 查询:

SELECT * FROM my_table WHERE concat(uuid, '') like '%123%';

而且它有效。这个

CONCAT
强制转换为
VARCHAR
并且
LIKE
函数完成了他的工作。知道这一点后,我做到了:

final Path<UUID> uuidField = from.get("uuid");
var cast = cb.function("concat", String.class, uuidField, cb.literal(""));
cb.like(cast, String.format("%%%s%%", stringValue));

工作完美。我希望这对其他人有帮助。

正如@HaroldH所说,这是一个奇怪的要求,但发生在我的项目中。


0
投票

您必须使用“.as()”JPA 函数,以便本机调用“cast”。

即您的用例:

cb.like(from.get("uuid").as(String.class), String.format("%%%s%%", stringValue));
最新问题
© www.soinside.com 2019 - 2025. All rights reserved.