JPQL Check greater than less than date today in #Query annotation - java

I want to check weather validTill date is greater than today using JPQL. I know that I can achieve this by following.
Query q = em.createQuery("select e from MyEntity e where e.validTill > :today ");
and pass the :today parameter. But this is not I wanted. I want to do this using #Query annotation in the CrudRepository in Spring.
This is my code segment in the CrudRepository
#Query("SELECT e FROM MyEntity e WHERE e.validFrom < TODAY")
Iterable<MyEntity> findAllValid();
I don't know what I should put at the place TODAY to get the today's date. Please help me.

I found it. it's like this..
#Query("SELECT e FROM MyEntity e WHERE e.validFrom < CURRENT_DATE")
Iterable<MyEntity> findAllValid();
CURRENT_DATE - is evaluated to the current date (a java.sql.Date instance).
CURRENT_TIME - is evaluated to the current time (a java.sql.Time instance).
CURRENT_TIMESTAMP - is evaluated to the current timestamp, i.e. date and time
(a java.sql.Timestamp instance).

Related

date comparison in JPQL

I have a comparison of two dates in my application code. The code is in Flutter, but is easy, so you can understand it even if you donĀ“t know Dart:
selectedDayCalendar.isAfter(item.canceledDate.add(Duration(days: 15)))
Here I want to know when the date selected in Calendar is after other date + 15 days. The problem is:
data can only be shown when date 1 is before or on the same day as date 2 (+ 15 days). If I do this validation in the application, the API will still bring data that I will not use, so I wanted to do this validation in the API itself. The API can only bring in data where:
!selectedDayCalendar.isAfter(item.canceledDate.add(Duration(days: 15)))
How I can do this validation in JPQL Query SELECT?
JPQL doesn't support adding days to a date sadly, so you'll have to use a native query:
SELECT e FROM Item e WHERE DATEADD(DAY, 15, e.canceledDate) < CURRENT_DATE
I think something like that.
But some people don't like the mix of using native and JPQL queries combined.
RESOLVED:
I put Instant.now() in a local variable, then I created another one with instant.now() + 15 days. I passed these two variables by parameter to the function JPQL Query.
it was like this:
Instant startDate = Instant.now();
Instant endDate = startDate.plus(15, ChronoUnit.DAYS);
return eventService.findByTrainerLoginCanceledDateBetween(startDate, endDate);
and JPQL:
#Query(
"SELECT e " +
"FROM Event e " +
"WHERE e.status = '' OR e.canceledDate BETWEEN :startDate AND :endDate"
)
List<Event> findEventByLoginAndCanceledDateBetween(Instant startDate, Instant endDate);

Substract years from current_date in JPQL

I want to delete the rows which are older than 2 years. In SQL I do it like this:
DELETE FROM table WHERE creation_date < (current_date - interval '2 year');
Now I want to do the same for my JPA Repository in Java with the JPQL.
In JPQL I get an error because interval is not known and the "-"(minus) is not correct.
JPQL Query
#Query("DELETE FROM table t WHERE t.creation_date < (current_date - interval '2 year')")
I would appreciate any suggestion.
You can calculate the dateTime in the application, assuming you are using LocalDateTime for creation_date
LocalDateTime dateTime = LocalDateTime.now().minus(Period.ofYears(2));
and pass the parameter in JPQL
#Query("DELETE FROM table t WHERE t.creation_date < :dateTime")
void deleteByDateTime(LocalDateTime dateTime)

Spring Data #Query - How to get current date + day

I would like to get records that have date_time column is in a week from now, in a month from now
I have a query like this
public interface BookingRepository extends JpaRepository<Booking, Long> {
#Query("SELECT b " +
"FROM BOOKING b " +
"WHERE b.date_time < NOW() + INTERVAL 7 DAY and b.date_time > NOW()")
List<Booking> getListBooking();
}
In MySQL, NOW() + INTERVAL 7 DAY is working but in JPA #Query, I don't know which function is correspond to it.
In this situation, I have to use dynamic query instead of native query. So I'd like to use dynamic query and face this problem.
Please help.
Thank you!
there is no date_add in JPA so you would have few options:
use native query https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#_native_queries
implement custom jpa function for date modifications
parametrize query
personally i would go with query parametrization as it is easier to test and maintain in the long-run.

JPA, custom query and dates

I'm facing a strange issue. I've search including here in stack overflow and for JPA and Custom query I should specified the parameter. So I have a query string since I have over 14 fields but I'm facing issues with the dates. I'm always getting the IllegalStateException
INFO: query STRING = SELECT t FROM Tickets t WHERE t.startdate > :startDate AND t.enddate < :endDate ORDER BY t.status DESC
WARNING: #{ticketController.search}: java.lang.IllegalStateException: Query argument startDate not found in the list of parameters provided during query execution.
as for my query:
Query q = em.createQuery(query).setParameter("startDate", startDate, TemporalType.TIMESTAMP).setParameter("endDate", endDate, TemporalType.DATE);
Although I'm getting that the parameter is not found, I have it in the setParameter and also set in the query as seen in the INFO line.
Any ideas?
Thanks in advance
EDIT:
INFO: query STRING = SELECT t FROM Tickets t WHERE t.startdate > ?1 AND t.enddate < ?2 ORDER BY t.status DESC
WARNING: #{ticketController.search}: java.lang.IllegalStateException: Query argument 1 not found in the list of parameters provided during query execution.
q = em.createQuery(query).setParameter(1, startDate, TemporalType.TIMESTAMP).setParameter(2, endDate, TemporalType.TIMESTAMP);
Also and as advised, I've checked that the Date I'm using is java.util.Date. and in the entity class I have as Timestamp. But still I cannot have this working and not sure where I am failing.
Just to make sure that all the things are as they should, I forced the query to be string and I got the correct Exception:
INFO: query STRING = SELECT t FROM Tickets t WHERE t.startdate > :startDate AND t.enddate < :endDate ORDER BY t.status DESC
WARNING: #{ticketController.search}: java.lang.IllegalArgumentException: You have attempted to set a value of type class java.lang.String for parameter startDate with expected type of class java.util.Date
But then again, I change to date and it fails :S
I've checked the reasons for this IllegalStateException:
And from the debug and from the javadoc I get the following:
getResultList
IllegalStateException - if called for a Java Persistence query language UPDATE or DELETE statement.
I'm not doing a update nor delete :/
EDIT 2: Adding the Entity relevant part:
#Basic(optional = false)
#NotNull
#Column(name = "startdate")
#Temporal(TemporalType.TIMESTAMP)
private Date startdate;
#Column(name = "enddate")
#Temporal(TemporalType.TIMESTAMP)
private Date enddate;
AS for the database creating script the columns are being created like this:
startdate timestamp with time zone NOT NULL,
endate timestamp with time zone,
If I do a normal SQL query like:
"select * from tbl_tickets where startdate > '2012-02-01 00:00:00' and enddate < '2013-03-18 23:59:50'"
I get the desired results. I guess I could do with native query but that would be going around the problem and not fixing this issue, right?
EDIT 3: Although I had everything set up properly, the init of the bean was calling again the query without the args ( sorry and thank you all for your help. It helped me checking what was amiss)
javadoc for both
setParameter(String name, java.util.Date value, TemporalType temporalType)`
setParameter(String name, java.util.Calendar value, TemporalType temporalType)`
states:
Throws: IllegalArgumentException - if the parameter name does not correspond to a parameter of the query or if the value argument is of incorrect type
Since you didn't provide full code, verify that:
Java value startDate is of type java.util.Date or java.util.Calendar.
SQL column startDate has valid SQL date type TIMESTAMP.
I think that there should be a space between :(colon) and startDate in between. May be it is considering :startDate as a single word. Try this once
Try
String query = "SELECT t FROM Tickets t WHERE t.startdate > ?1 AND t.enddate < ?2 ORDER BY t.status DESC";
Query q = em.createQuery(query).setParameter(1, startDate, TemporalType.TIMESTAMP).setParameter(2, endDate, TemporalType.DATE);
Query q = em.createQuery(query).setParameter("startDate", startDate, TemporalType.TIMESTAMP).setParameter("endDate", endDate, TemporalType.DATE);
If you carefully look at the setParameter you're using, it says that this setParameter requires a Positional Parameter, whereas, seeing your query, it seems you've used Named Parameter.
Hence, the IllegalStateException. Either change your query to provide Positional Parameters, or the setParameter to provide Named Parameters as input.
This is how you provide Positional Parameter in the query.
String query = "SELECT t FROM Tickets t WHERE t.startdate > ?1 AND t.enddate < ?2 ORDER BY t.status DESC";
....
Query q = em.createQuery(query).setParameter(1, startDate, TemporalType.TIMESTAMP).setParameter(2, endDate, TemporalType.DATE);

JPQL to query java.util.Date field of entity using date portion of date time

I have an entity with a date field (java.util.Date). Normally the date is saved as for example 2012-10-19 21:29:03.000. My database is MySQL.
Now I need to query the database, through JPQL, using strictly the date portion, i.e., 2012-10-19. How would I do that?
That can be done by giving TemporalType when setting parameter:
Date param ...
Query q = em.createQuery("SELECT a FROM EntityA a WHERE a.someDate > :param");
q.setParameter("param", param, TemporalType.DATE);

Categories

Resources