JPA Query using between and Instant not working

Viewed 1026

I'm trying to make a query to retrieve some data which has been created between two dates (represented as Instant).

Here below an extract from the Entity I'm using:

@Entity
public class HistoricalData {
@Id
@GeneratedValue
private Long id;

@Column
private String name;

@CreationTimestamp
private Instant timestamp;

@Column
private Double price;

}

And the query I've written to retrieve the data between the two Instants;

@Query("select h from HistoricalData h where h.timestamp between :timestampStart and :timestampEnd and upper(name) = upper(:name)")
List<HistoricalData> findHistoricalDataBetween(@NonNull Instant timestampStart, @NonNull Instant timestampEnd, @NonNull String name);

Which produces this SQL query:

select historical0_.id as id1_5_, historical0_.price as price2_5_, historical0_.timestamp as timestam3_5_ from historical_data historical0_ where (historical0_.timestamp between ? and ?) and upper(historical0_.name)=upper(?)

Also I wrote the "hibernate JPA" query just to try but no success:

List<HistoricalData> findHistoricalDataByTimestampAfterAndTimestampBeforeAndName(@NonNull Instant timestampStart, @NonNull Instant timestampEnd, @NonNull String name);

Keep in mind that all the above queries compile correctly and do not throw any exception, they just retrieve nothing from the database

The database I'm using is a latest version of MariaDB and the connector version is the 2.7.2 Also the SpringBoot version I'm using is the 2.5.3

Here is DDL from the table definition (automatically generated from Hibernate):

create table historical_data
(
id        bigint   not null primary key,
price     double   null,
timestamp datetime not null,
name      varchar  not null
);

An this is how the timestamp looks like in the database:

enter image description here

Even though records between those two Instants are present in the database I'm still getting nothing as a result from the query.

1 Answers

Looks like the reason is a time zone. MySQL driver uses incorrect time zone transformations, using a default local time zone in place of a connection time zone (or vice versa).

Just debug this query inside MySQL driver to have fun and figure out what happens.

You can add parameters to the database URL to see which actual values are passed for the prepare statement

jdbc:mysql://<DATABASE_URL>?logger=com.mysql.cj.log.Slf4JLogger&profileSQL=true
Related