I am using HQL with DATE_ADD (mysql function) as below
String hql =
"select count(*) " +
"from ProgramGroupEvent as eventLog " +
"where eventLog.id= :id" +
"and DATE_ADD( eventLog.eventDate, INTERVAL :interval MINUTE) > now()";
long count = 0;
try {
count = ((Long)sess.createQuery( hql )
.setLong( "id", id)
.setInteger("interval", interval )
.iterate().next()).longValue();
} catch (HibernateException e) {
e.printStackTrace();
}
But hibernate throws a token error as below
antlr.NoViableAltException: unexpected token: :
at org.hibernate.hql.internal.antlr.HqlBaseParser.identPrimary(HqlBaseParser.java:4016) ~[hibernate-core-4.1.7.Final.jar:4.1.7.Final]
at org.hibernate.hql.internal.antlr.HqlBaseParser.primaryExpression(HqlBaseParser.java:859) ~[hibernate-core-4.1.7.Final.jar:4.1.7.Final]
at org.hibernate.hql.internal.antlr.HqlBaseParser.atom(HqlBaseParser.java:3390) ~[hibernate-core-4.1.7.Final.jar:4.1.7.Final]
PS: I am using Hibernate 4.1.7
I did further research and found out the issue. The problem is Hibernate is not able parse the syntax. As per it's expectation, this is not well formed HQL syntax.
https://forum.hibernate.org/viewtopic.php?f=1&t=982317&view=previous
I fixed by replacing
DATE_ADD( eventLog.eventDate, INTERVAL :interval MINUTE) > now()";
With
time_to_sec(timediff( now() , eventLog.eventDate )) < :seconds";
Hopefully, this can help for someone
Your query require two parametrs
pharmacyOid
interval
But in your query parameters id and interval are used.
Your query should look:
count = ((Long)sess.createQuery( hql )
.setLong( "pharmacyOid", id)
.setInteger("interval", interval )
.iterate().next()).longValue();
Related
As it gives unexpected token: DAY. Anybody suggest what should be the alternative of DAY here
select p from Patient p where p.id in(select a.patient.id from p.assessments a where (a.appointmentDate <=(CURRENT_DATE + interval 6 DAY) and a.appointmentDate >=(CURRENT_DATE)) and a.chatBotStatus='LINK_CREATED')
As I am new in data JPA so any answer will be appreciable
Try using native query something like this:
#Query(value = "select * from activation_codes a where a.type = :type and a.id_account = :id_account and a.creation_time <= NOW() - :hoursAgo * INTERVAL '1 hour'", nativeQuery = true)
please refer this - https://stackoverflow.com/a/51954042/4076451
Caused by: org.hibernate.hql.internal.ast.QuerySyntaxException:
unexpected token: INTERVAL near
Here is my query:
private static final String USERS_NOT_ACTION_IN_LAST_MONTH = select u from myTable u where u.lastDate + INTERVAL 30 DAY <= CURDATE();
#Override
public List<MyEntity> getItemOlderThanMonth() {
Query q = _entityManager.createQuery(USERS_NOT_ACTION_IN_LAST_MONTH, MyEntity.class);
return q.getResultList();
}
I want to get records older than 30 days.
You can calculate current date by query parameter(current_date- 30)
private static final String USERS_NOT_ACTION_IN_LAST_MONTH = select u from myTable u where u.lastDate <= :calculated_date;
where calculated_date=current_date -30 days.
By using _entityManager.createQuery hibernate sql (hql) script is created and hibernate doesn't have INTERVAL key word.
But createNativeQuery is native sql and behaves as normal sql script. So for mysql db INTERVAL key word should work. So smth like that
_entityManager.createNativeQuery("select * from myTable u where u.lastDate + INTERVAL 30 DAY <= CURDATE()");
I need help converting some sql to hibernate sql.
SQL:
String sql = "select time, hour(time) as hour, minute(time) as minute "
+ "from db where time >= DATE_ADD(now(), INTERVAL -24 HOUR) "
+ "group by 2 order by time LIMIT 500";
I use SQLQuery to add scalars. I tried this for HQL:
String hql = "select time, hour(time), minute(time) from db as O "
+ "where O.time >= :time group by 2 order by O.time";
Query query = session.createQuery(hql);
query.setDate("time", calend.getTime()); //calend is a Calendar object
However, this doesn't work. Error says it's an hql error.
Instead of using setDate try using setParameter.
From this link about HQL dates:
"setDate" will truncate the HQL date value and ignore the hours, minutes, seconds.
Using setParameter will interpret the values as the parameter that you indicated by :variable.
I am trying to delete 1 month old records from my table using domain.executeUpdate as follows
Bugrerun.executeUpdate("delete Bugrerun b where b.complete = 1 and b.date
< date_sub(curdate(), INTERVAL 1 MONTH) ")
i am trying to use a MySQL date function inside the query.
But this fails with the error
org.hibernate.hql.ast.QuerySyntaxException: unexpected token: 1 near line 1
, column 97
How can we use the My SQL date time functions inside executeUpdate statements
Note that this table has lot of data so fetch and delete individual records will not work
You can try with the below query, just need to validate whether the HQL functions are supported in MySQL dialect:
Bugrerun.executeUpdate("delete Bugrerun b \
where b.complete = 1 \
and month(current_date()) > month(b.date) \
or year(current_date()) > year(b.date)")
You could implement your own Database dialect to include that functionality.
Another option is to do this:
Calendar cal = Calendar.getInstance();
cal.setTime(new Date());
cal.add(Calendar.MONTH, -1);
Bugrerun.executeUpdate("delete Bugrerun b where b.complete = 1 and b.date
< :oneMonthAgo", [oneMonthAgo: cal.time])
Not all mysql functions are available. You can take a look at MySQLDialect that is used by hibernate (and grails) to see the functions you have available for you:
http://grepcode.com/file/repository.springsource.com/org.hibernate/com.springsource.org.hibernate/3.3.1/org/hibernate/dialect/MySQLDialect.java#MySQLDialect
If you want, you can try to use Groovy SQL to execute a SQL statement instead of an HQL statement. If you do that, in your controller or service you should declare a dataSource attribute so you get DataSource injected:
class MyController {
DataSource dataSource
def execSql(){
def sql = new Sql(dataSource)
sql.execute("delete from bugrerun where complete = 1 and date < date_sub(curdate(), INTERVAL 1 MONTH) ")
render "done"
}
}
This really puzzled for hours, I searched all over the internet, but got no working solution. Can someone point where the problem is ... thanks !
I created my own dialect class
public class MySQLDialectExtended : MySQLDialect
{
public MySQLDialectExtended()
{
RegisterFunction("date_add_interval", new SQLFunctionTemplate(NHibernateUtil.Date, "date_add(?1, INTERVAL ?2 ?3)"));
}
}
Then I try to use it as follows:
query.Append(
" ( date_add_interval(D.ApprovalDate, 1, YEAR) < current_timestamp() < date_add_interval(D.RenewalDate, -1, YEAR) )");
It fails with following exception:
NHibernate.Hql.Ast.ANTLR.QuerySyntaxException : Exception of type 'Antlr.Runtime.NoViableAltException' was thrown. near line 1, column 677
where the column number is at the end of the first 'YEAR' word.
Edit:
here is my configuration
<property name="dialect">MyCompanyName.MySQLDialectExtended, MyCompanyName</property>
<property name="hbm2ddl.keywords">none</property>
Can you post the whole NHibernate query?
UPDATE: Well, the query is obviously malformed and erroneous:
Select distinct D from MBIgnition.Core.Domain.Model.Deal D where 1=1 and
( (D.MortgageStatus = 30 ) or
(D.MortgageStatus = 35 ) or
(D.MortgageStatus = 40 ) or
(D.MortgageStatus = 45 ) or
(D.MortgageStatus = 55 ) or
(D.MortgageStatus = 50 ) ) and
// next line is erroneous as the first AND operator does not have a lefthand side operand
(( and ( date_add_interval(D.ApprovalDate, 1, YEAR) < current_timestamp() < date_add_interval(D.RenewalDate, -1, YEAR) ) ) )
As you can see, there's an AND operator in your code without any lefthand-side arguments. There should be something wrong with your HQL. Double check it again and if you couldn't pinpoint the error it will be useful to post the HQL or the criteria building code here.