简体   繁体   中英

Hibernate converts null string to byte and crashes query

This is probably the weirdest error I've seen on hibernate in my life

I've a spring-boot project

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.5.3</version>
    <relativePath/> <!-- lookup parent from repository -->
</parent>

I need to lookup later what exact versions of hibernate and jpa this starter is using...

The problem is: I've a custom function in my database as follows

CREATE OR REPLACE FUNCTION IS_EXTRA_MATCH(addressExtra text, containedValue text)
 returns boolean
 language plpgsql
 LEAKPROOF
 CALLED ON NULL INPUT
 PARALLEL SAFE

The code of the function itself is irrelevant, it works, and I've tested with a range of inputs, nulls, empty string... etc etc etc etc

The function works, no unexpected results occur

Then I've a custom query on my jpa repository which uses this function

 @Query("SELECT a FROM address a WHERE a.zipcode = :zipcode AND a.number = :num AND CAST(IS_EXTRA_MATCH(a.extra, :extra) AS java.lang.Boolean) = true")
   Set<AddressEntity> findByZipcodeAndNumberAndExtra(@Param("zipcode") String zipcode, @Param("num") int num, @Param("extra") String extra);

The first thing that bothers me is that if I remove '= true' from end of query it won't work... so even when I cast the element to boolean, Hibernate doesn't know how to evaluate it without something to compare... but this is not the problem

The problem is WHEN :extra is null, the query crashes with the error

2022-08-12 00:52:19.529 ERROR 1 --- [io-10000-exec-4] o.a.c.c.C.[.[.[/].[dispatcherServlet]    : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.dao.InvalidDataAccessResourceUsageException: could not extract ResultSet; SQL [n/a]; nested exception is org.hibernate.exception.SQLGrammarException: could not extract ResultSet] with root cause

org.postgresql.util.PSQLException: ERROR: function is_extra_match(character varying, bytea) does not exist
  Hint: No function matches the given name and argument types. You might need to add explicit type casts.
  Position: 624

The whole stacktrace is giant and as I've read it, irrelevant... what this is saying that somehow Hibernate converts the null string into a bytea and the function can't deal with that.

I've tried to force a cast CAST(:extra as text) but it won't work

Is there any way to tell Hibernate to use NULL AS NULL and not as this weird data type?

Please if you read that far don't come with the suggestion

why don't you check for null before calling the function...

If anyone knows the proper way to handle this problem please help me

I've tried to force a cast CAST(:extra as text) but it won't work

Maybe tell us what it is that doesn't work? For one, you should be using cast(:extra as String) as the cast target types for JPQL/HQL are domain model basic types and not database specific types. Share stack traces or SQL that is generated which doesn't work.

The problem here really is the JDBC driver and inability to infer a parameter type in combination with Spring Data being unable to pass parameter values in a typed fashion when values are null. Hibernate can't infer the type of the parameter, because it doesn't know the second parameter of IS_EXTRA_MATCH is String / text . So it tries to infer the type based on the value you pass. Since you pass null , Hibernate will default to some JDBC methods like setBytes to set the value.

The answer Hibernate has for this, is the TypedParameterValue class, which you can use to pass typed parameter values.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM