我将SpringBoot与PostgreSQLJDBC42.2.13和Hibernate5.3.18.final一起使用,在添加 IS NULL
检查uuid集合时,hibernate/postgresql无法确定集合的数据类型。
实体
class Element {
@Column
private UUID uuid;
}
存储库
@Query("SELECT e FROM Element e WHERE (:uuids) IS NULL OR e.uuid IN (:uuids)")
List<Element> findByUuidIn(@Param("uuids") Collection<UUID> uuids);
查询执行
elementRepository.findByUuidIn(List.of(UUID.randomUUID())); // works fine!
elementRepository.findByUuidIn(null); // -> Throws exception
从跟踪日志记录绑定参数
org.hibernate.type.descriptor.sql.BasicBinder - binding parameter [1] as [OTHER] - [null]
org.hibernate.type.descriptor.sql.BasicBinder - binding parameter [2] as [OTHER] - [null]
例外情况
Caused by: org.postgresql.util.PSQLException: ERROR: could not determine data type of parameter $1
at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2532)
at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:2267)
at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:312)
at org.postgresql.jdbc.PgStatement.executeInternal(PgStatement.java:448)
at org.postgresql.jdbc.PgStatement.execute(PgStatement.java:369)
at org.postgresql.jdbc.PgPreparedStatement.executeWithFlags(PgPreparedStatement.java:153)
at org.postgresql.jdbc.PgPreparedStatement.executeQuery(PgPreparedStatement.java:103)
at jdk.internal.reflect.GeneratedMethodAccessor582.invoke(Unknown Source)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at org.apache.tomcat.jdbc.pool.StatementFacade$StatementProxy.invoke(StatementFacade.java:114)
at com.sun.proxy.$Proxy398.executeQuery(Unknown Source)
at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.extract(ResultSetReturnImpl.java:60)
... 114 common frames omitted
临时解决方案
将query参数更改为string,并在query中强制转换列类型。
@Query("SELECT e FROM Element e WHERE (:uuids) IS NULL OR CAST(e.uuid AS string) IN (:uuids)")
List<Element> findByUuidIn(@Param("uuids") Collection<String> uuids);
elementRepository.findByUuidIn(null); // works fine!
org.hibernate.type.descriptor.sql.BasicBinder - binding parameter [1] as [VARCHAR] - [null]
org.hibernate.type.descriptor.sql.BasicBinder - binding parameter [2] as [VARCHAR] - [null]
向社区提问
有没有办法提供 null
作为参数的uuid集合,并具有 IS NULL
检查?
是不是hibernate中没有绑定参数类型的bug UUID
和用途 OTHER
而不是使用 null
集合作为参数?
是不是postgresqljdbc中的一个bug在使用时没有确定参数的类型 OTHER
类型?
1条答案
按热度按时间nzk0hqpo1#
hibernate有三种基本类型Map到
java.util.UUID
:org.hibernate.type.UUIDBinaryType
Map到二进制数据类型(bytea
)org.hibernate.type.UUIDCharType
已Map到CHAR
,也可以阅读VARCHAR
org.hibernate.type.PostgresUUIDType
Map到postgresql uuid,通过Types#OTHER
,符合postgresql jdbc驱动程序定义。很多postgresql类型Map到
java.sql.Types.OTHER
,例如org.postgresql.util.Pgobject
(位变化),org.postgresql.geometric.Pgpoint
(点),org.postgresql.geometric.Pgbox
(方框),java.util.UUID
(uuid)(看这个)。所以,当您传递时,postgresqljdbc驱动程序无法确定参数的数据类型null
.解决方案
您可以按以下方式更正查询:
它将允许您使用
Collection<UUID>
已传递参数类型。但是,实际上这与您的解决方法类似,因为它将生成以下sql:您可以更改表的列定义:
然后按以下方式Map此列:
然后您就可以查询它而无需任何强制转换: