1

I have a native query in Spring Boot as such:

@Query(value = "SELECT t.* FROM Transaction t WHERE " +
    "t.datetime >= TO_TIMESTAMP(?1,'YYYY-MM-ddTHH:MI') " +
    "AND t.datetime < TO_TIMESTAMP(?2,'YYYY-MM-ddTHH:MI') " +
    "AND (t.location_1 = ?3 or ?3 is null) " +
    "LIMIT ?4",
    nativeQuery = true)
    List<Transaction> findBySearchTerms(@Param("fromDateTime") String fromDateTime,
            String toDateTime,
            Integer location1,
            Integer maxCount
            );

For the location1, it may be null. When i run this query with location1 null, it returns the error message: org.postgresql.util.PSQLException: ERROR: operator does not exist: bigint = bytea

After which i tried casting on parameter 3:

"AND (?3 is null or t.location_1 = cast(?3 as bigint)) " +

It also results in an error: org.postgresql.util.PSQLException: ERROR: cannot cast type bytea to bigint.

I have searched for similar questions on stackoverflow and followed some of the recommendations but it still does not work. Any ideas?

Eugene
  • 1,013
  • 1
  • 22
  • 43

3 Answers3

10

I had a same issue and I managed to fix it by casting it to BIGINT but first to TEXT and then BIGINT. I use Spring Boot 2.2 and Kotlin, but same is for Java.

I have following example:

 @Query(
        """
         SELECT
         f.id,
         f.name,
         c.id AS company_id,
         c.name AS company_name
         FROM facility f
         WHERE (:companyId IS NULL OR f.company_id = CAST(CAST(:companyId AS TEXT) AS BIGINT))  
        """
)
@Transactional(readOnly = true)
    fun exampleMethod(@Param("companyId") companyId: Long? = null):List<Result>

If I do not cast it I get error:

Caused by: org.postgresql.util.PSQLException: ERROR: operator does not exist: bigint = bytea
  Hint: No operator matches the given name and argument type(s). You might need to add explicit type casts

and I I cast it just to BIGINT once, then error is:

Caused by: org.postgresql.util.PSQLException: ERROR: cannot cast type bytea to bigint
codemozzer
  • 181
  • 1
  • 6
  • See also > When the value for that column is null, hibernate uses the wrong type https://stackoverflow.com/a/64383530/1503636 – user1503636 Oct 08 '21 at 16:10
1

Just reverse your parameter in query like this.

@Query(value = "SELECT t.* FROM Transaction t WHERE " +
    "t.datetime >= TO_TIMESTAMP(?1,'YYYY-MM-ddTHH:MI') " +
    "AND t.datetime < TO_TIMESTAMP(?2,'YYYY-MM-ddTHH:MI') " +
    "AND ( ?3 is null or t.location_1 = ?3) " +
    "LIMIT ?4",
    nativeQuery = true)
    List<Transaction> findBySearchTerms(@Param("fromDateTime") String fromDateTime,
            String toDateTime,
            Integer location1,
            Integer maxCount
            );
Sanjay
  • 2,481
  • 1
  • 13
  • 28
  • 1
    Does not work for me, the error message shows the position number being changed. It will still evaluate the second portion t.location_1 = ?3 – Eugene May 23 '19 at 05:48
  • for string comparsion, don't use t.location_1 = ?3 but use t.location_1 LIKE ?3 – davey Jan 23 '20 at 00:39
0

You may have two different query to handle Null and Not Null. Call these two methods based on location is null or not null

@Query(value = "SELECT t.* FROM Transaction t WHERE " +
"t.datetime >= TO_TIMESTAMP(?1,'YYYY-MM-ddTHH:MI') " +
"AND t.datetime < TO_TIMESTAMP(?2,'YYYY-MM-ddTHH:MI') " +
"AND (t.location_1 = ?3 ) " +
"LIMIT ?4", nativeQuery = true)

@Query(value = "SELECT t.* FROM Transaction t WHERE " +
"t.datetime >= TO_TIMESTAMP(?1,'YYYY-MM-ddTHH:MI') " +
"AND t.datetime < TO_TIMESTAMP(?2,'YYYY-MM-ddTHH:MI') " +
"AND (t.location_1 is null) " +
"LIMIT ?4",
nativeQuery = true)
Rowi
  • 545
  • 3
  • 9
  • Thanks, I guess this is the only way for now. The solution will become messy when I have more than 1 parameter that can be null.. – Eugene May 23 '19 at 05:49