How to use date_format when using JPQL/JPA - java

I am doing Java EE with MySQL as database and implementing JPA on my codes.
I have no problem retrieving the data from MySQL Workbench but when I change my syntax to JPQL's it does not work.
For e.g. in MySQL - it works
SELECT date_format(s.date,'%Y, %m, %d') from Transactions s;
in JPQL - it does not
SELECT date_format(s.date,'%Y, %m, %d') from TransactionEntity s;
How do i modify to suit the JPA query?
Note:
in JPQL the following works
SELECT s.date from TransactionEntity s;

SQL function date_format is not part of JPQL, as any documentation would tell you, so don't see the point in just pushing SQL into JPQL and expecting it to work.
What you can do with JPA 2.1 is invoke it as follows
function("date_format", s.date, '%Y, %m, %d')
where function is a way to invoke any native SQL function. This clearly means you lose database independence because that function is not valid on all datastores.

Sql function is available in JPQL. My JPA version is 1.11.9. Sample group by day query:
#Query(value = "SELECT count(ac) as count, function('date_format', max(ac.subscriptionStartDate), '%Y, %m, %d') as date FROM MyTable ac " +
"WHERE ac.subscriptionStartDate BETWEEN :startDate AND :endDate GROUP BY function('date_format', ac.subscriptionStartDate, '%Y, %m, %d')")
public List<Map<String,Object>> findRegisteredCustomersHistory(#Param("startDate") Date startDate, #Param("endDate") Date endDate);
The result of the query is the list that records the number of records grouped by days in formatted form.
Sample rows:
count: 3, date: 2019, 09, 10
count: 1, date: 2019, 09, 11
for your question, try this in JPQL:
#Query(value = "SELECT function('date_format', s.date, '%Y, %m, %d') as date from Transactions s;")

Related

How to add date in mysql database from Hibernate/Spring Jpa

I use spring boot, and I want to add 1 year to a specific column in mysql database
String queryRecherche = "UPDATE myTable t SET t.dateDebut = DATE_ADD(t.dateDebut, INTERVAL 1 YEAR) WHERE.id = 3 ";
Query query = em.createQuery(queryRecherche);;
query.executeUpdate();
But I get the folowing error :
org.hibernate.query.sqm.ParsingException: line 1:66 no viable alternative at input 'DATE_ADD(t.dateDebut,INTERVAL1'
Have you please any suggestions to do this.
You're using Hibernate 6 (I can tell by the error message), so the correct HQL syntax to use is:
UPDATE MyEntity t SET t.dateDebut = t.dateDebut + 1 year WHERE t.id = 3
You had three errors in your query:
You referred to the name of a table instead of the name of an entity class in the UPDATE clause.
You used the unportable MySQL DATE_ADD function instead of the portable HQL date/time arithmetic described here.
The syntax of your WHERE clause was garbled.
Perhaps you meant for this to be a native SQL query, in which case you called the wrong method of Session. But there's no need to use native SQL for the above query. As you can see, HQL is perfectly capable of expressing that query.
You can use SQL directly, via createNativeQuery, or register a new function as shown in this example to call it from HQL

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);

JPA query to search only by date by ignoring time

I need help to write the JPA query (or function) to remove timestamps in search queries.
I am using MySQL DB.
My table consist of create_date(datetime) column.
My entity mapped with create_date using LocalDateTime
#Column(name = "create_date")
private LocalDateTime createDate;
I can achieve using the Mysql query in two ways.
select * from table_name where DATE(create_date) between '2019-07-01' and '2019-07-31'
select * from table_name where create_date between '2019-07-01 00:00:00' and '2019-07-31 23:59:59'.
I can achieve results using JPA also bypassing timestamp like
"where createDate between '2019-07-01 00:00:00' and '2019-07-31 23:59:59'"
Is there a way to build a query without passing time?
Something similar to Mysql query No.1
OHHHHHH I found an answer.
where DATE(createDate) between '2019-07-01' and '2019-07-31' is working.

Get data for specific month from MS Access 2016 db

Good day, I am struggling with an sql select query from my java application. My application connects with an MS Access database. I would like to retrieve all records logged during a specific month. This is my statement:
Select * from tbl q
Join (
Select s.Customer from tbl s
Where Month(s.LogDate) = 1 And Year(s.LogDate) = 2017);
Problem is that my resultset returns data logged for both January 2017 and December 2016. I have tried different approaches one of which was to pass an sql date(#date#) but I still get the same result. What am I doing wrong?
You shouldn't need the join or the subquery. Try
Select * from tbl where month(logdate)=1 and year(logdate)=2017

NamedParameterJDBCTemplate and function syntax on different RDBMSs

I need to support both, Oracle und SQL Server. I have pretty identical procedures named get_current_date in both DBs. Now I have a query:
SELECT col1, col2 FROM table WHERE colDate < get_current_date()
This works beautifully in Oracle but lacks the dbo. prefix when executed in SQL Server.
Should Spring be able to handle that? What other options do I have? I dont think it should be necessary to determine the DB type myself.
Thank you!
Every JDBC driver should support the JDBC function escapes (defined in section 13.4.1 and listed in appendix D of the JDBC 4.1 spec). For the CURRENT_DATE it is CURRENT_DATE or CURRENT_DATE().
You can call this in a query as
SELECT col1, col2 FROM table WHERE colDate < {fn CURRENT_DATE}
You can query the list of supported functions of your specific driver with DatabaseMetaData.getTimeDateFunctions()
BTW: This assumes you just want the current date of the database. It is not a general solution for calling user defined functions in your query.
Should Spring be able to handle that?
--> get_current_date() is database method/procedure (may it be of database or your custom) so it is dependent on database, Spring would not take care of that.
What other options do I have?
--> Well you can put current date in query in code so it will be independent of database what you use. Something like :
String sql = "SELECT col1, col2 FROM table WHERE colDate < " + new Date();
How about get current date in java something like:
Calendar cal = Calendar.getInstance();
currentDate = cal.getTime();
and then you do:
SELECT col1, col2 FROM table WHERE colDate < currentDate

Categories

Resources