I'm struggling on a seemingly simple hibernate use-case and cannot figure out what's going on :
This is my entity :
@Entity @Data @JsonIgnoreProperties({"hibernateLazyInitializer", "handler"}) public class Event { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private int id; @Column(columnDefinition = "timestamp without time zone", nullable = false) @Temporal(TemporalType.TIMESTAMP) private Date date; @Column(columnDefinition = "text") private String status; public Event() {} } And this is my native query, called with 'date' being potentially NULL :
@Query(value = "SELECT e FROM Event e WHERE :date is null or DATE(e.date) = :date") Page<Event> findEvents(Pageable pageable, @Param("date") Date date); The date parameter passed to the function is already truncated as a date (i.e. no hours, minutes, etc), but the database entry isn't, that's why I use the DATE() sql function in the left part of the comparison.
Where run with a NULL date, the query crashes with this error :
Caused by: org.postgresql.util.PSQLException: ERROR: operator does not exist: date = bytea Indice : No operator matches the given name and argument type(s). You might need to add explicit type casts. From what I understand, SQL standard doesn't short-circuit condition evaluations, so the second part is always evaluated. On the other hand, Hibernate is unable to infer the 'date' type because it's null, so it's injected in the request as binary, hence the error.
I tried this variant, with the same results :
@Query(value = "SELECT e FROM Event e WHERE :date is null or DATE(e.date) = COALESCE(:date, '2000-01-01')") Page<Event> findEvents(Pageable pageable, @Param("date") Date date); EDIT : I also tried this one :
@Query(value = "SELECT e FROM Event e WHERE :date is null or DATE(e.date) = CAST(:date AS date)") With another error that reflects the same issue :
Caused by: org.postgresql.util.PSQLException: ERROR: cannot cast type bytea to date EDIT2 :
To make sure that the second condition part is never evaluated if the parameter is NULL, I tried this approach, using the CASE WHEN .. THEN syntax :
@Query(value = "SELECT e FROM Event e WHERE (case when :date is null then true else (DATE(e.date) = cast(:date AS date)) end)" But Hibernate doesn't like it, and I don't know why ...
Caused by: org.hibernate.hql.internal.ast.QuerySyntaxException: unexpected AST node: case near line 1, column 30 [SELECT e FROM Event e WHERE (case when :date is null then true else (DATE(e.date) = cast(:date AS date)) end)]
Page<Event> findEvents(Pageable pageable, @Param("date") @Temporal java.util.Date date);? It could be, that this triggers Spring to set the parameter as "Datenull".