JPA CriteriaBuilder date operations - java

I'm trying to translate my sql query to JPA Criteria Builder which is used in project which I'm working on and I stuck on date operation (PostgreSQL 9.3), I have a bit in where clause:
...AND cl.due_date + '3 YEARS' <= '2016-01-01 10:27:16.473' and cl.due_date + '3 YEARS' >= '2008-01-01 10:27:16.473'....
The problem is that I'm not able to create a Predicate object for "due_date" + "3 YEARS".
Does anyone know how to manage to do that?
Thanks in advance

You need to add (or subtract) the 3 years in Java, not in the query:
Calendar dueDateCalPlus3Years = Calendar.getInstance();
dueDateCalPlus3Years.set(set(year, month, date, hourOfDay, minute, second);
dueDateCalPlus3Years.add(Calendar.YEAR, -3);
Date dueDatePlus3Years = dueDateCalPlus3Years.getTime();
Expression<Date> cl; // initialize it!
Predicate predicate = criteriaBuilder.greaterThanOrEqualTo(cl, dueDatePlus3Years);
To be more concise, you can use the interval mapping CriteriaBuilder#between(), and the query you have posted results in:
Date date1;
Date date2;
Predicate predicate = criteriaBuilder.not(criteriaBuilder.between(cl, date1, date2));

Related

Extracting date from timestamp in HQL for comparison in a where clause

I want to extract (year, month, dayOfMonth) from a timestamp field using HQL for comparison in a where clause.
Example:
Query hibernateQuery = session.createQuery("select sum(t.amount) from Transaction t " +
"where extract_date(t.timestampField) = :date");
hibernateQuery.setParameter("date", LocalDate.of(2018, 10, 11));
System.out.println( hibernateQuery.getSingleResult() );
So I am looking for a function like this pseudo function extract_date(t.timestampField) that I've used in example above.
This should work properly
Query hibernateQuery = session.createQuery("select sum(t.amount) from Transaction t " +
"where DATE(t.timestampField) = :date");
hibernateQuery.setParameter("date", new java.sql.Date.valueOf("2018-10-11"));
Note: the data type returned by DATE(...) function is java.sql.Date so if you are having a java.time.LocalDate it can be easily converted to java.sql.Date as follow:
LocalDate localDate = LocalDate.of(2018, 10, 11);
java.sql.Date sqlDate = java.sql.Date.valueOf(localDate);
It is discussed in the following Q/A.
https://stackoverflow.com/a/29168526/7972796

Java Spring JPA Repository between date query

Hello I have entity and have createdAt filed specified like this:
#JsonIgnore
#Column(name = "created_at")
#Temporal(TemporalType.TIMESTAMP)
protected Date createdAt;
Every entity includes this field. Now I have complicated SQL query which calculates profit between dates. Query looks like this:
#Query("SELECT SUM(CASE WHEN t.outcome = true THEN - t.amount ELSE t.amount END) as income " +
"FROM Transaction t " +
"WHERE t.property = :property " +
"AND t.createdAt BETWEEN :dateFrom AND :dateTo")
Double getPropertyProfitBetweenDates(#Param("property")Property property, #Param("dateFrom")Date dateFrom, #Param("dateTo")Date dateTo);
The function that parses dates as I want looks like this:
Calendar start = Calendar.getInstance();
start.add(Calendar.MONTH, -i);
start.set(Calendar.DAY_OF_MONTH, 1);
start.set(Calendar.HOUR_OF_DAY, 0);
start.set(Calendar.MINUTE, 0);
start.set(Calendar.SECOND, 0);
start.set(Calendar.MILLISECOND, 0);
Calendar end;
end = (Calendar) start.clone();
end.add(Calendar.MONTH, 1);
end.add(Calendar.DAY_OF_MONTH, -1);
Date dateFrom = start.getTime();
Date dateTo = end.getTime();
When I try to access data via repository I call method like this:
transactionService.getPropertyProfitBetweenDates(property, dateFrom, dateTo)
Every time I receive null, but when I mannualy run query in mysql workbench I get correct records. Could you please help me solving this problem out?
I fixed the problem using java.sql.Date

JPA to_char function for date in Java

I have this query and an oracle DB. When I try to execute it, I never receive an answer from DB. Edit: Query return 0 rows. I know that is for Date because if I use the same query with TO_CHAR with Toad this works. How i can add in Java code TO_CHAR function? Thank you.
public List<PrivacySospensiva> getAllByCf(String cf,Long idsuperpratica,String stato,Date dataCensimento){
TypedQuery<PrivacySospensiva> query = entityManager.createQuery("select u from PrivacySospensiva u where u.id_superpratica = :idSuperpratica AND u.stato = :stato AND u.cf = :cf AND u.data_censimento = :dataCensimento", PrivacySospensiva.class);
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH24:mm:SS");
sdf.format(dataCensimento);
query.setParameter("idSuperpratica", idsuperpratica);
query.setParameter("stato",stato);
query.setParameter("cf",cf);
query.setParameter("dataCensimento",dataCensimento);
List<PrivacySospensiva> result = query.getResultList();
return result;
}
The date format is wrong and should be yyyy-MM-dd HH:mm:ss (0-23 hours) or yyyy-MM-dd kk:mm:ss (1-24 hours). And SS would be microseconds.
Fortunately the code does not use it; all probably an experiment. One would need to do:
String t = sdf.format(dataCensimento);
query.setParameter("dataCensimento", t);
(sdf.format will not alter dataCensimento.)

convert java.sql.Timestamp to java.sql.Date

I have a Timestamp and Date variables and i want to compare it for equality (only date part of course). It was surprise for me that contructor Date(long) saves time part, so this code does not work correct:
date = resultSet.getDate(1);
timestamp = resultSet.getTimestamp(2);
//...
if (date.equals(new Date (timestamp.getTime())) ...
I solve this with code like:
DateFormat dateFormat = new SimpleDateFormat ("yyyyMMdd");
if (date.equals(dateFormat.parse(dateFormat.format(timestamp)))) ...
Or i can convert timestamp to date in sql query, but i need a timestamp representation too. Is there a better way to cut a time part from Timestamp.
Java 8 approach of conversion:
Date date = Date.valueOf(timestamp.toLocalDateTime().toLocalDate());
And vice versa:
Timestamp timestamp = Timestamp.valueOf(date.toLocalDate().atStartOfDay());
Using the method from this answer we get:
date = resultSet.getDate(1);
timestamp = resultSet.getTimestamp(2);
Calendar cal1 = Calendar.getInstance();
Calendar cal2 = Calendar.getInstance();
cal1.setTime(date);
cal2.setTimeInMillis(timestamp.getTime());
boolean sameDay = cal1.get(Calendar.YEAR) == cal2.get(Calendar.YEAR) &&
cal1.get(Calendar.DAY_OF_YEAR) == cal2.get(Calendar.DAY_OF_YEAR);
It's worth reading the linked answer as it talks about the shortcomings of this method with respects to timezones and so on (and some of the other answers to that question give alternate approaches which you may prefer).
You have three options with this one.
First is to use Yoda time and class DateTimeComparator.getDateOnlyInstance()
Second is to use commons from apache and DateUtils.isSameDay()
Third use the [Calendar] and set the time and compare the year, month and day of year only. As Dave Webb proposed.
Another approach is to use the "day" part of the epoch value:
Date d = new Date();
Timestamp t = new Timestamp(d.getTime());
long dateEpochDays = d.getTime() % (1000*60*60*24);
long timeStampEpochDays = t.getTime() %(1000*60*60*24);
System.out.println("date: " + dateEpochDays + " timestamp: " + timeStampEpochDays);

How do I calculate days since a record entry? Android, SQLite, Java

I have a database with a field for a stored date. I would like to be able calculate the days between the recorded date and today.
I ended up using:
mDb.execSQL("UPDATE "+DATABASE_PLANTS_TABLE+" SET "+ KEY_PLANT_DAYS+
" = (SELECT julianday('now') - julianday("+KEY_DATE+") FROM"+ DATABASE_PLANTS_TABLE+")");
select (strftime('%s','now')-strftime('%s', data1))/86400.0 as days from table
Use the Joda Time Days class for this:
Date dateInDb = getStoredDate();
Date today = new Date();
Days days = Days.daysBetween(new DateTime(dateInDb), new DateTime(today));
int numberOfDays = days.getDays();

Categories

Resources