SQL Query with JpaRepository: how to filter LocalDateTime based only on year, month and day?

Luke :

I have an entitity "Show" that has a LocalDateTime variable called "start":

public class Show {
    //--other code---
    @Column(nullable = false)
    private LocalDateTime start;
    //--other code---
}

I want to select from my DB based only on year, month and day, while ignoring hour and minute.

My current query is:

@Query(value = "SELECT * FROM show s WHERE s.event_id = :eventId 
AND DATEPART(year, s.start) = DATEPART(year, :dateSearch) 
AND DATEPART(month, s.start) = DATEPART(month, :dateSearch) 
AND DATEPART(day, s.start) = DATEPART(day, :dateSearch)", nativeQuery = true)
Page<Show> findAllFiltered(@Param("eventId") Long eventId, @Param("dateSearch") LocalDateTime dateSearch, Pageable page);

When I try to execute that query I get an 500 error code with the following message:

"could not prepare statement; nested exception is org.hibernate.exception.GenericJDBCException: could not prepare statement"

edit: made the query in the code block more easily readable

Andreas :

I would suggest you change to using a date/time range, instead of a single value. That would also perform better in the query, if the table happens to have an index on event_id, start

Something like this:

@Query(value = "SELECT *" +
                " FROM show s" +
               " WHERE s.event_id = :eventId" +
                 " AND s.start >= :startDate" +
                 " AND s.start < :endDate", nativeQuery = true)
Page<Show> findAllFiltered(@Param("eventId") Long eventId,
                           @Param("startDate") LocalDateTime startDate,
                           @Param("endDate") LocalDateTime endDate,
                           Pageable page);

Note that endDate is exclusive, as is most commonly done with all range operations in Java.

You could then add a helper method, if desired:

Page<Show> findAllFiltered(@Param("eventId") Long eventId,
                           @Param("dateSearch") LocalDateTime dateSearch,
                           Pageable page) {
    LocalDateTime startDate = dateSearch.truncatedTo(ChronoUnit.DAYS);
    LocalDateTime endDate = startDate.plusDays(1);
    return findAllFiltered(eventId, startDate, endDate, page);
}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=166313&siteId=1