如何在 JPQL 中检查 UUID 空值?

Posted

技术标签:

【中文标题】如何在 JPQL 中检查 UUID 空值?【英文标题】:How to check UUID null value in JPQL? 【发布时间】:2021-09-15 05:52:03 【问题描述】:

我正在使用 JPA/Hibernate。所以我想在 JPQL 中做 nullCheck,但是当我这样做时它并不能确定 dataType。

JPQL 查询:

  @Query("select a from Attribute a where :attributeId is null OR a.id = :attributeId")
  Page<Attribute> findByAttributeId(@Param("attributeId") UUUID attributeId);

例外:

原因:org.postgresql.util.PSQLException: ERROR: could not 确定参数 $1 的数据类型 在 org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2532) 在 org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:2267) 在 org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:312) 在 org.postgresql.jdbc.PgStatement.executeInternal(PgStatement.java:448) 在 org.postgresql.jdbc.PgStatement.execute(PgStatement.java:369) 在 org.postgresql.jdbc.PgPreparedStatement.executeWithFlags(PgPreparedStatement.java:153) 在 org.postgresql.jdbc.PgPreparedStatement.executeQuery(PgPreparedStatement.java:103) 在 jdk.internal.reflect.GeneratedMethodAccessor582.invoke(未知来源) 在 java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 在 java.base/java.lang.reflect.Method.invoke(Method.java:566) 在 org.apache.tomcat.jdbc.pool.StatementFacade$StatementProxy.invoke(StatementFacade.java:114) 在 com.sun.proxy.$Proxy398.executeQuery(未知来源) 在 org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.extract(ResultSetReturnImpl.java:60) ... 省略了 114 个常用帧

我在互联网上搜索了很多关于此主题的内容,但找不到解决方案。 我不想在服务层处理它。

我试过了:

    PostgreSql CAST 函数 检查为字符串 @Type 注释。

JPQL 中是否有检查 UUID 空值的方法?

【问题讨论】:

如果存储库接口,还要添加方法声明。 你为什么要这样做? @pirho 对不起,我忘记了。 @cjgmj 有时,attributeId 为空。我不想在服务层处理它,因为应用程序中的所有 nullchecks 都是在查询中处理的。出于一致性原因,我想在查询中处理它 但是如果你的 id 是 null 你必须从 db 中返回 id 为 null 的对象? 【参考方案1】:

我在使用 JPA 3.0 + EclipseLink + PostgreSQL 时遇到了类似的错误,这是由于参数的自动转换引起的。尝试将stringtype=unspecified 添加到您的连接 URL: jdbc:postgresql://SERVER:5432/mydatabase?stringtype=unspecified

【讨论】:

其实我是这样连接到 postgre 的【参考方案2】:

在网上查了一下,找到了解决办法。 由于 PostgreSQL 无法确定 dataType,我们可以从之前声明它为 TypedParameterValue。

TypedParameterValue attributeId = new TypedParameterValue(PostgresUUIDType.INSTANCE, UUIDUtil.toUUID(attributeId));
Page<Attribute> attributes = attributeRepo.findByAttributeId(attributeId);

然后在 JPQL 中进行 nullChecking,转换为 org.hibernate.type.PostgresUUIDType: (在IDE中可以显示为错误,但实际编译)

 @Query("select a from Attribute a where (cast(:attributeId as org.hibernate.type.PostgresUUIDType) OR a.id = :attributeId)")
 Page<Attribute> findByAttributeId(@Param("attributeId") TypedParameterValue attributeId);

在本机查询中:

 @Query(value = "select * from attribute a where (cast(:attributeId as uuid) OR a.id = :attributeId)",nativeQuery = true)
 List<Attribute> findByAttributeId(@Param("attributeId") TypedParameterValue attributeId);

【讨论】:

以上是关于如何在 JPQL 中检查 UUID 空值?的主要内容,如果未能解决你的问题,请参考以下文章

如何将复杂的 SQL 查询转换为 JPQL?

如何在流分析中检查 JSON 属性中的空值?

如何在Javascript中检查空值?

如何在 oracle 中使用空值检查 last_modified 日期

如何在颤振发布方法中修复“未处理的异常:用于空值的空检查运算符”

当@include false 或@skip true 时,是不是可以在graphql 中使用空值UUID 进行查询