How to perform date operations in hibernate
Asked Answered
M

9

17

I want to perform data time operations using hibernate HQL.

I want to add and subtract two dates as well as I want to subtract 1 year or 1 month from a particular date.

How is this possible using HQL in hibernate?

Mogador answered 24/6, 2009 at 6:15 Comment(0)
B
7

See Performing Date/Time Math In HQL? for an example.

To use custom sql you must wrote an own hibernate dialect and register:

registerFunction("weekday", 
  new SQLFunctionTemplate(Hibernate.INTEGER, "to_char(?1,'D')") );
Brigandine answered 24/6, 2009 at 11:7 Comment(3)
Yes.. I saw that link but in Hibernate there is no provision given for adding or subtracting date properly. suppose if I want a date before a year using current_timestamp() of HQL. What should be done as there is no additional function given for that. Is there any better way? Thanks.Mogador
Hello, on following link I found detailed description of creating custom hibernate dialect for sql server. It is explained in last answer of the link. Hope it will help someone. forums.hibernate.org/viewtopic.php?f=1&t=995494Mogador
Hi amar4kintu, if my answer has helped, can you please vote or mark the answer with the green checkmark?Brigandine
L
10

You need to create your own dialect. Something like the following:

public class MyDialect extends MySQLInnoDBDialect{
      public MyDialect() {
      super();
      registerFunction("date_add_interval", new SQLFunctionTemplate(Hibernate.DATE, "date_add(?1, INTERVAL ?2 ?3)"));
      }
    }
Longinus answered 28/10, 2009 at 1:21 Comment(1)
Great ... now how You use this in code ... a small sample if possibleSeymour
B
7

See Performing Date/Time Math In HQL? for an example.

To use custom sql you must wrote an own hibernate dialect and register:

registerFunction("weekday", 
  new SQLFunctionTemplate(Hibernate.INTEGER, "to_char(?1,'D')") );
Brigandine answered 24/6, 2009 at 11:7 Comment(3)
Yes.. I saw that link but in Hibernate there is no provision given for adding or subtracting date properly. suppose if I want a date before a year using current_timestamp() of HQL. What should be done as there is no additional function given for that. Is there any better way? Thanks.Mogador
Hello, on following link I found detailed description of creating custom hibernate dialect for sql server. It is explained in last answer of the link. Hope it will help someone. forums.hibernate.org/viewtopic.php?f=1&t=995494Mogador
Hi amar4kintu, if my answer has helped, can you please vote or mark the answer with the green checkmark?Brigandine
T
5

This is an open issue in Hibernate. As of Hibernate 3.3 there is no standard way to handle date comparisons purely in HQL:

https://hibernate.atlassian.net/browse/HHH-2434

Hibernate 4.3 offers functions to access Date/Time in HQL which are:

current_timestamp() , current_date() , current_time()

Arithmetic operations can be managed by:

SECOND(...) , MINUTE(...) , HOUR(...) , DAY(...) , MONTH(...) , YEAR(...)
Twiggy answered 14/7, 2010 at 20:40 Comment(0)
M
5

In Hibernate/MySQL (at least) You can convert to and from a Unix Timestamp. Since the unix timestamp is an integer you can add an integer number of seconds to it.

FROM_UNIXTIME(UNIX_TIMESTAMP(date)+ (allowedTimeWindow*86400)) as deadline

It has limitations but it's a lot easier than the approaches above.

Mauchi answered 12/6, 2013 at 11:8 Comment(0)
J
1

Disclaimer: I am a Java novice

I was able to use current_date() >= fromDate AND dateadd(day, -1, getdate()) <= toDate in an HQL statement against a Sybase db in Hibernate 3.5.3, without registering any functions.

Juxtaposition answered 10/9, 2012 at 21:2 Comment(0)
J
1

The Hibernate issue Fred Haslam has referenced has been solved. With Hibernate 6.0+ versions, you can add Temporal Unit operations to date fields as simple as this:

Select m From MyObject m Where m.dateField + 10 MONTH - 5 DAY < current_date

*current_date being a Hibernate constant for current date.

Related Hibernate Issue

Temporal Units

Jurist answered 17/6 at 14:51 Comment(0)
M
0

Usage sample of approach with dialect for JPA + Hibernate 4.3.1 + MySQL 5

public class SampleMySQL5InnoDBDialect extends org.hibernate.dialect.MySQL5InnoDBDialect {

public SampleMySQL5InnoDBDialect() {
    super();
    registerFunction("date_sub_days", new SQLFunctionTemplate(StandardBasicTypes.DATE, "date_sub(?1, interval ?2 day)"));
}

then for your class with mapping annotation:

@NamedQuery(name = "SampleEntity.getSampleEntitiesForGapOverlapCalculations", query = "from SampleEntity as se where "
    + "((se.toDate between :startDate and :endDate) or (date_sub_days(se.toDate, se.duration) between :startDate and :endDate)) order by se.toDate asc, se.duration desc")

SampleEntity has toDate field of type java.sql.Date and duration integer field (duration in days) and we are calculating fromDate = toDate - duration and selecting all entities which have fromDate or toDate inside interval [startDate, endDate].

Macgregor answered 14/6, 2013 at 14:27 Comment(0)
L
0

Hibernate4.3 provides native functions to access Dates/Timestamps and to perform arithmatic operations on them

Here is the link to the documentation of what expressions can be used in HQL. Few of which i am mentioning: To access date/time:

current_date(), current_time(), and current_timestamp()

Arithmetic operations can be done by following. These functions take Time as input:

second(...), minute(...), hour(...), day(...), month(...), and year(...)

One can get absolute difference of in HQL by

current_timestamp() - dateInstance

where dateInstance can have definition

@Column(name = "updated_at")
@Temporal(TemporalType.TIMESTAMP)
private java.util.Date updatedAt;

The result is in 0.1 seconds. So for a absolute difference of 1 second, the above expression will give result as 10.

So a query would look like :

select t from Table t where (current_timestamp() - updatedAt)>600
Leakey answered 9/10, 2015 at 11:50 Comment(0)
W
0

Postgres users...

registerFunction("dateadd", new SQLFunctionTemplate(StandardBasicTypes.DATE, "(?1 + INTERVAL ?2)"));

with SQL usage like:

now() < dateadd(:mydate, '-1 day')
Wernerwernerite answered 7/4, 2018 at 2:8 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.