I have a hql to show my data based on between(to_date), but i got Could not locate named parameter error
this is my code
SimpleDateFormat sdf1 = new SimpleDateFormat("dd-MM-yyyy");
Date date1 = Calendar.getInstance().getTime();
String tgl1 = sdf1.format(date1);
String Tanggal_awal = tgl1+" 00:00:00";
System.out.println(Tanggal_awal);
SimpleDateFormat sdf2 = new SimpleDateFormat("dd-MM-yyyy");
Date date2 = Calendar.getInstance().getTime();
String tgl2 = sdf2.format(date2);
String Tanggal_akhir = tgl2+" 23:59:59";
System.out.println(Tanggal_akhir);
Query LoadSource = session_source.createQuery("select CLIENT,SERVICE,SERVICE_TYPE,PROVIDER_CODE,COUNT(*) FROM SwitcherServiceSource" +
" where TIMESTAMP between to_date(':awal','dd-MM-yyyy HH24:MI:SS') and to_date(':akhir','dd-MM-yyyy HH24:MI:SS')" +
" and PROVIDER_CODE is not null group by CLIENT,SERVICE,SERVICE_TYPE,PROVIDER_CODE order by CLIENT,SERVICE,SERVICE_TYPE,PROVIDER_CODE");
LoadSource.setParameter("awal", Tanggal_awal);
LoadSource.setParameter("akhir", Tanggal_akhir);
any help will be pleasure :)
You do not need to quote your parameters. i.e.:
Instead of having where TIMESTAMP between to_date(':awal','dd-MM-yyyy HH24:MI:SS') and to_date(':akhir','dd-MM-yyyy HH24:MI:SS'), you should write where TIMESTAMP between to_date(:awal,'dd-MM-yyyy HH24:MI:SS') and to_date(:akhir,'dd-MM-yyyy HH24:MI:SS')
And even better, you can (and you should) even avoid binding a string to that parameter. You can bind a Date/Timestamp, so that the query is even more effective and readable: where TIMESTAMP between :awal and :akhir, and do something similar to this in your code:
Calendar cal = Calendar.getInstance();
cal.set(Calendar.HOUR_OF_DAY, 0);
cal.set(Calendar.MINUTE, 0);
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.MILLISECOND, 0);
Date fromDate = cal.getTime();
cal.set(Calendar.HOUR_OF_DAY, 23);
cal.set(Calendar.MINUTE, 59);
cal.set(Calendar.SECOND, 59);
Date toDate = cal.getTime();
Query loadSource = session_source.createQuery("select blablabla FROM SwitcherServiceSource" +
" where TIMESTAMP between :awal and :akhir " +
" and blablabla group by blabla order by blablabla");
loadSource.setParameter("awal", fromDate );
loadSource.setParameter("akhir", toDate);
Related
I have an SQL table in my Android project, that has a KEY_DATE field in Date format.
KEY_DATE + " DATE,"
My table is populated from the java code (date in dd/mm/yy format).
So now I need to make several date-related queries and something isn't working.
I need to make selections from a table for today, this month and this year.
Here's what I tried:
DateFormat dateFormat = new SimpleDateFormat("dd/MM/yy");
Date todayD = new Date();
dateFormat.format(todayD);
String today = dateFormat.format(todayD);
Calendar cal = Calendar.getInstance();
cal.set(Calendar.DAY_OF_MONTH, 1);
Date firstDay = cal.getTime();
dateFormat.format(firstDay);
String selectQuery = "SELECT * FROM " + TABLE_PAYMENTS + "WHERE "
+ KEY_DATE +" BETWEEN " + firstDay + " AND " + today;
The query returns empty even though there's a lot of data for that period.
I believe something is wrong with data formats here. Can you help me to solve this?
Thank you in advance.
You are not formatting firstD, so you only get from the first day of the month at the current time on;
You should either use single quotes around the dates in your queries or use prepared statements, otherwise your server will understand your dates as math operations;
When querying for date ranges, remember that if you don't specify an hour with your date SQL will by default take it as zero hour (0:00:00.0000). If you use "between startDate and today", you get only midnight of today. If you use "between startDate and tomorrow", you get midnight of tomorrow too. You should use "date >= startDate and date < tomorrow" to get the proper range.
When writing queries with dates, I always prefer to use ISO format for the date strings: yyyy-MM-dd.
Calendar cal = Calendar.getInstance();
DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
Date todayD = new Date();
cal.setTime(todayD);
cal.add(Calendar.DATE, 1);
Date tomorrowD = cal.getTime();
String today = dateFormat.format(tomorrowD);
cal.set(Calendar.DAY_OF_MONTH, 1);
Date firstD = cal.getTime();
String firstDay = dateFormat.format(firstD);
String selectQuery = "SELECT * FROM TABLE_PAYMENTS WHERE KEY_DATE >= '" + firstDay + "' AND KEY_DATE < '" + today + "'";
The problem is with the date formats for the data present inside the database and the date formats that you are passing (strings) to the sql query.
It is not a good practice to pass dates as string parameters to the sql query, so I strongly suggest use preparedStatement as shown below:
Date todayD = new Date();
Calendar cal = Calendar.getInstance();
cal.set(Calendar.DAY_OF_MONTH, 1);
Date firstDay = cal.getTime();
String selectQuery = "SELECT * FROM TABLE_PAYMENTS WHERE BETWEEN ? AND ?" ;
//create preparedStatement here
preparedStatement.setDate(1, firstDay);
preparedStatement.setDate(2, todayD);
I want to reset java.util.Date to the beginning of the day
using
Date date = new Date();
Calendar cal = new GregorianCalendar();
cal.setTime(date);
cal.set(Calendar.HOUR_OF_DAY, 0);
cal.set(Calendar.MINUTE, 0);
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.MILLISECOND, 0);
date = cal.getTime();
with
Date date = new Date();
DateFormat df = new SimpleDateFormat("dd/MM/yyyy");
String s=df.format(date);
try {
date = df.parse(s);
} catch (ParseException ex) {
}
Which one is better?
This one's better in terms of clarity and readability, though both gives same output.
Date date = new Date();
Calendar cal = new GregorianCalendar();
cal.setTime(date);
cal.set(Calendar.HOUR_OF_DAY, 0);
cal.set(Calendar.MINUTE, 0);
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.MILLISECOND, 0);
date = cal.getTime();
With help of Apache Commons org.apache.commons.lang3.time.DateUtils you can also get the desired result like this:
DateUtils.truncate(new java.util.Date(), java.util.Calendar.DATE));
First solution (manipulation via Calendar) is definitly better. The second solution is just a rather ugly workaround using string-manipulation, that will most likely be slower than the first one.
You can for first approach and you need not set time in Calendar.
// Date date = new Date();
Calendar cal = new GregorianCalendar();
// cal.setTime(date);
cal.set(Calendar.HOUR_OF_DAY, 0);
cal.set(Calendar.MINUTE, 0);
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.MILLISECOND, 0);
Date date = cal.getTime();
String string_Date = "2014-06-11"; //my string date
SimpleDateFormat simpleFormat = new SimpleDateFormat("yyyy-MM-dd");
// Date startTimestam = simpleFormat.parse(string_Date);
Timestamp startTimestam = Timestamp.valueOf(string_Date);
Calendar cal = Calendar.getInstance();
cal.setTime(startTimestam);
cal.set(Calendar.HOUR_OF_DAY, 0);
cal.set(Calendar.MINUTE, 0);
cal.set(Calendar.SECOND, 1);
starTimeStamp = new Timestamp(cal.getTime().getTime());
// will get output date is "2014-06-11 00:00:01"
here I don't want use simple Format for converting string to date or timestamp,
if above code run I will get exception is illegalArgumentException i.e.
Timestamp format must be yyyy-mm-dd hh:mm:ss[.fffffffff]**
is it possible with out format converts string date.
if possible very helpfully for me.
Your question is not very clear because of below:
1) Why do you want to avoid using SimpleDateFormat?
2) Do you want to convert String to Timestamp or Date to Timestamp?
If you want to convert String to Timestamp, then it is straightforward (without using SimpleDateFormat):
String timeValueStr="00:00:01";
String startTimeStr="2014-06-11" + " " + timeValueStr;
Timestamp startTimestamp = Timestamp.valueOf(startTimeStr);
If you want to convert String to Date and then Date to Timestamp:
//String to Date conversion
String startTimeStr = "2014-06-11";
SimpleDateFormat simpleFormat = new SimpleDateFormat("yyyy-MM-dd");
Date d = simpleFormat.parse(startTimeStr);
//Date to Timestamp conversion
Calendar cal = Calendar.getInstance();
cal.setTime(d);
cal.set(Calendar.HOUR_OF_DAY, 0);
cal.set(Calendar.MINUTE, 0);
cal.set(Calendar.SECOND, 1);
Timestamp startTimestamp = new Timestamp(cal.getTime().getTime());
And of course, if you MUST avoid SimpleDateFormat, then here is the code to convert String to Timestamp first and then to Date (There is no way to convert String to Date directly without using SimpleDateFormat):
String timeValueStr="00:00:01";
String startTimeStr="2014-06-11" + " " + timeValueStr;
Timestamp startTimestamp = Timestamp.valueOf(startTimeStr);
Date d = new Date(startTimestamp.getTime());
I am trying to figure out how to get a date that is exactly one year less than the current date and pass it as a parameter to HQL.
I tried to use Calendar. But I am lost in converting this to right Date format required for Oracle.
Calendar cal = Calendar.getInstance();
cal.setTime(new Date());
cal.set(Calendar.HOUR_OF_DAY, 0);
cal.set(Calendar.MINUTE, 0);
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.MILLISECOND, 0);
cal.add(Calendar.YEAR, -1);
String dateLimit = cal.getTime().toString();
Date dateFormatter = new SimpleDateFormat("dd-MMM-yyyy").parse(dateLimit); // This one shows I need to either wrap it up in try catch or specify in throws.
//Date cutOffDate = dateFormatter.parse(dateLimit); //tried this. no avail
queryBuilder.append(" and c.dateOfContact >= :cutOffDate ");
parameters.put("cutOffDate", dateFormatter);
Alternatively, are there any Hibernate built-in function for date manipulation? All I want is to pass a date to the query, which is a year less than the current date.
Oracle date format is dd-MMM-yyyy. (ex: 21-Jun-2013)
i think this will work:
parameters.put("cutOffDate", cal.getTime());
If the type of c.dateOfContact is java.util.Date or java.sql.Date than cal.getTime() has to work.
Date d = cal.getTime();
Query query = em.createQuery(QUERYSTRING)setParameter("cutOffDate", d);
The above should work, don't format your date as a string, because then you will be comparing a String and a Date.
In my Data base dates are as 2012-04-09 04:02:53 2012-04-09 04:04:51 2012-04-08 04:04:51, etc, I need to retrieve data which have current date in there date field. I mean i need to match only 2012-04-09' . How can i do it using hibernate criteria.
Use Restrictions.between() to generate a where clause which the date column is between '2012-04-09 00:00:00' and '2012-04-09 23:59:59'
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date fromDate = df.parse("2012-04-09 00:00:00");
Date toDate = df.parse("2012-04-09 23:59:59");
criteria.add(Restrictions.between("dateField", fromDate, toDate));
Please note that all the properties used in the Criteria API is the Java property name , but not the actual column name.
Update: Get fromDate and toDate for the current date using JDK only
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.HOUR_OF_DAY, 0);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 0);
Date fromDate = calendar.getTime();
calendar.set(Calendar.HOUR_OF_DAY, 23);
calendar.set(Calendar.MINUTE, 59);
calendar.set(Calendar.SECOND, 59);
Date toDate = calendar.getTime();
criteria.add(Restrictions.between("dateField", fromDate, toDate));
Like this?
criteria.add(Expression.eq("yourDate", aDate))
fromDate.setTime(new Date());
fromDate.set(Calendar.HOUR_OF_DAY, 0);
fromDate.set(Calendar.MINUTE, 0);
fromDate.set(Calendar.SECOND, 0);
fromDate.set(Calendar.MILLISECOND, 0);
This code is extremely dangerous ... if the day is switch to daylight saving time (e.g. 06.04.1980) you end up in following exception!!!
java.lang.IllegalArgumentException: HOUR_OF_DAY: 0 -> 1day
HQL: from human pat where year(pat.birthdate) = :start_day and month(pat.birthdate) = :start_month and year(pat.birthdate) = :start_year ");
params.put("start_day", startDate.get(Calendar.DAY_OF_MONTH));
params.put("start_month", startDate.get(Calendar.MONTH) + 1);
params.put("start_year", startDate.get(Calendar.YEAR));
The year/month/day functions use the underlying db functions (extract, ...) and compares only these values. Therefore I did not need to set the time to 0 which leads to the above described exception.
just an example out of my mind how I solved the problem! Maybe it helps
How-to do it in Hibernate has already been said. You can prepare the Timestamp objects in the Java code using, for example, the following aproach:
Calendar cFrom = Calendar.getInstance();
cFrom.setTime(new Date()); /* today */
cFrom.set(Calendar.HOUR_OF_DAY, 0);
cFrom.set(Calendar.MINUTE, 0);
cFrom.set(Calendar.SECOND, 0);
cFrom.set(Calendar.MILLISECOND, 0);
Timestamp from = new Timestamp(cFrom.getTime().getTime());
Calendar cTo = Calendar.getInstance();
cTo.setTime(new Date()); /* today */
cTo.set(Calendar.HOUR_OF_DAY, 23);
cTo.set(Calendar.MINUTE, 59);
cTo.set(Calendar.SECOND, 59);
cTo.set(Calendar.MILLISECOND, 999);
Timestamp to = new Timestamp(cTo.getTime().getTime());
final String QUERY = ""
+ "SELECT tr "
+ "FROM Type tr "
+ "WHERE tr.timestamp >= :timestampFrom AND tr.timestamp <= :timestampTo";
Query query = entityManager.createQuery(QUERY);
query.setParameter("timestampFrom", from);
query.setParameter("timestampTo", to);
#SuppressWarnings("unchecked")
List<Type> ts = (List<Type>)query.getResultList();
The easiest way is to fetch all records having date between the beginning and end of a given day:
WHERE date BETWEEN :from AND :to
And compute from and to in your Java code.
For computing midnights:
import static org.apache.commons.lang.time.DateUtils.ceiling;
import static org.apache.commons.lang.time.DateUtils.truncate;
Date someDay = new Date();
Date from = truncate(someDay, Calendar.DAY_OF_MONTH);
Date to = new Date(ceiling(someDay, Calendar.DAY_OF_MONTH).getTime() - 1);
Restrictions.between("dateColumn", midnight1, midnight2)
The following code will work
Calendar fromDate = Calendar.getInstance();
fromDate.setTime(new Date());
fromDate.set(Calendar.HOUR_OF_DAY, 0);
fromDate.set(Calendar.MINUTE, 0);
fromDate.set(Calendar.SECOND, 0);
fromDate.set(Calendar.MILLISECOND, 0);
Calendar toDate = Calendar.getInstance();
toDate.setTime(new Date());
toDate.set(Calendar.HOUR_OF_DAY, 23);
toDate.set(Calendar.MINUTE, 59);
toDate.set(Calendar.SECOND, 59);
toDate.set(Calendar.MILLISECOND, 999);
criteria.add(Restrictions.between("loadDate", fromDate.getTime(),
toDate.getTime()));
// datetime comparison Hibernate 4.3
Select c from Customer c where c.date<{d '2000-01-01'}