sql到hql抛出异常

Posted

技术标签:

【中文标题】sql到hql抛出异常【英文标题】:sql to hql throwing exception 【发布时间】:2017-01-11 09:51:22 【问题描述】:

我在我的项目中使用休眠,我正在尝试将现有的 sql 查询从 DaoImplementation 类转换为 hql,

我的sql查询是

JdbcTemplate select = new JdbcTemplate(dataSource);
    String sql = "SELECT * FROM (SELECT site_id,rtc,sigplan,cycle_time,health,phase_no,phase_time,active_groups,groupscolour,ip "+
                 "FROM status_data where  rtc>='" + fromDate + "' and rtc<'" + toDate + "' and "+
                 "site_id=" + SiteId + " order by rtc desc limit "+recordLimit+" )as temp ORDER BY RTC ASC";

我编写了 hql 版本来从 HealthLog 表中获取数据

String hql = " select f from (select h from HealthLog h where rtc>='"+fromDate+"' and rtc <'"+toDate+"' "
            + "and siteId = "+siteId+" order by rtc desc limit "+limit+" ) as f order by rtc asc ";
    return super.readListByHql(hql);

但是上面的hql抛出如下异常

org.hibernate.hql.internal.ast.QuerySyntaxException: unexpected token: ( near line 1, column 16 [ select f from (select h from com.traff.hibernate.model.HealthLog as h where rtc>='1974-08-01 14:10:00.0' and rtc <'1974-09-01 23:46:20.6' and siteId = 20 order by rtc desc limit 50000 ) as f order by rtc asc ]
at org.hibernate.hql.internal.ast.QuerySyntaxException.convert(QuerySyntaxException.java:54)
at org.hibernate.hql.internal.ast.QuerySyntaxException.convert(QuerySyntaxException.java:47)
at org.hibernate.hql.internal.ast.ErrorCounter.throwQueryException(ErrorCounter.java:79)
at org.hibernate.hql.internal.ast.QueryTranslatorImpl.parse(QueryTranslatorImpl.java:276)
at org.hibernate.hql.internal.ast.QueryTranslatorImpl.doCompile(QueryTranslatorImpl.java:180)
at org.hibernate.hql.intern

我也尝试了下面的代码 sn-p 但这给了我错误的结果

Criteria criteria = createEntityCriteria();     
    criteria.add(Restrictions.ge("rtc", fromDate));
    criteria.add(Restrictions.lt("rtc", toDate));
    criteria.add(Restrictions.eq("siteId", siteId));
    criteria.setMaxResults(limit);
    criteria.addOrder(Order.asc("rtc"));            
    criteria2 = criteria;
    criteria2.addOrder(Order.desc("rtc"));      
    return criteria2.list();

实现结果的正确方法是什么?

【问题讨论】:

哪个版本的休眠? @NicolasFilotto 4.1.9.Final 您不能在 HQL 的 from 子句中使用子查询。 ***.com/questions/7269010/… 【参考方案1】:

首先,正如 cmets 中已经提到的,您不能在 HQL 的 FROM 子句中执行子查询。 见:Hibernate Documentation

其次,HQL不支持limit关键字。 通常你会使用query.setFirstResult(0)query.setMaxResults(recordLimit) 方法,其中查询具有查询接口的类型。但是由于您在子查询中使用限制,所以没有办法。 见:How to set a limit to inner query in Hibernate?

一些选项:

    使用本机 SQLQuery 因为您只在外部查询中排序。您只能在 Java 中执行内部查询和排序。

选项 2 的示例:

Session session = factory.openSession();
Query query = session
    .createQuery("FROM HealthLog "
        + "WHERE rtc >= :rtcL and rtc < :rtcG and siteId = :siteId "
        + "ORDER BY rtc DESC");
query.setParameter("rtcL", fromDate);
query.setParameter("rtcG", toDate);
query.setParameter("siteId", siteId);
query.setFirstResult(0);
query.setMaxResults(recordLimit);
List<HealthLog> res = query.list();
session.close();

Collections.sort(res, new Comparator<HealthLog>() 
  public int compare(HealthLog o1, HealthLog o2) 
    return o1.getRtc().compareTo(o2.getRtc());
  
);

上面的查询返回带有所有属性的 HealthLogs。如果您只想检索特定属性,您可以使用HealthLog 中的合适构造函数将SELECT new HealthLog(siteId,rtc,sigplan,cycle_time,...) 添加到您的查询中。

请注意,代码 sn-p 可能无法使用,因为我不知道您的模型和属性名称。

【讨论】:

以上是关于sql到hql抛出异常的主要内容,如果未能解决你的问题,请参考以下文章

hql语句异常

当我尝试运行此代码时抛出异常..(导入到 sql 数据库)

从 SQL Server 函数向存储过程抛出异常

T-SQL编程中的异常处理-异常捕获(try catch)与抛出异常(throw)

获取 PL/SQL 中重新抛出异常的完整堆栈跟踪(从点异常开始)

HSQLDB 在 Windows 上运行,但在 Linux 上抛出异常