Hibernate and date comparisons

独自空忆成欢 提交于 2019-12-25 08:54:03

问题


Let's say I have a due date and a reminder timespan. How do I find the ones where due date is less than current date + reminder with Hibernate 3.6 criteria queries? In other words, I want to find my Events I've displayed the reminder. The reminder is a Long marking when the reminder should be sent either days or milliseconds, whichever is easier.

To summarize, my entities are following:

java.util.Date Event.DueDate
Long Event.Type.Reminder.Before // (in days or millis)

Examples

Today is 2012-06-11.
Included:
  DueDate is 2012-06-15 and Before is 30 days.
Excluded:
  DueDate is 2012-06-15 and Before is 1 day.

回答1:


Ultimately this is just what ANSI SQL calls date/time arithmetic and specifically you are looking for INTERVAL datatype handling. Unfortunately, databases vary widely on support for INTERVAL datatype. I really want to support this in HQL (and possibly criterias, although that relies on agreement in the JPA spec committee). The difficulty, like I said, is the varied (if any) support for intervals.

The best bet at the moment (through Hibernate 4.1) is to provide a custom function (org.hibernate.dialect.function.SQLFunction) registered with either the Dialect (search google to see how this is done) or the "custom function registry" (org.hibernate.cfg.Configuration#addSqlFunction). You'd probably want this to render to your database-specific representation of date-arith with an interval.

Here is an example using the Oracle NUMTODSINTERVAL function:

public class MySqlFunction implements SQLFunction
{
    public Type getReturnType(Type firstArgumentType,
                              Mapping mapping) throws QueryException
    {
        return TimestampType.INSTANCE;
    }

    public String render(Type firstArgumentType,
                         List arguments, 
                         SessionFactoryImplementor factory) throws QueryException
    {
        // Arguments are already interpreted into sql variants...
        final String dueDateArg = arguments.get( 0 );
        final String beforeArg = arguments.get( 1 );

        // Again, using the Oracle-specific NUMTODSINTERVAL
        // function and using days as the unit...
        return dueDateArg + " + numtodsinterval(" + beforeArg + ", 'day')";
    }

    public boolean hasArguments() { return true; }
    public boolean hasParenthesesIfNoArguments() { return false; }
}

You would use this in HQL like:

select ...
from   Event e
where  current_date() between e.dueDate and
       interval_date_calc( e.dueDate, e.before )

where 'interval_date_calc' is the name under which you registered your SQLFunction.



来源:https://stackoverflow.com/questions/10981736/hibernate-and-date-comparisons

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!