【问题标题】:Convert SQL Query to Hibernate Criteria and Projections将 SQL 查询转换为 Hibernate 标准和投影
【发布时间】:2018-10-31 01:32:55
【问题描述】:

我有来自 SQL 的查询:

select e.* 
from terminal_remote_deployment e
where id = (select top 1 e1.id
            from terminal_remote_deployment e1
            where e1.Terminal_info_id = e.Terminal_info_id
            order by e1.version desc
           );

我正在尝试像这样用 HQL 编写它:

final StringBuilder hql = new StringBuilder();
            hql.append(" from TerminalRemoteDeployment e");
            hql.append(" where e.id = (Select TOP 1 e1.id from TerminalRemoteDeployment e1 where e1.terminalInfo.id = e.terminalInfo.id order by e1.version desc)");

            Query query = getEntityManager().createQuery(hql.toString());
            resultList = (List<TerminalRemoteDeployment>) query.getResultList();

我在使用这种方法时遇到了错误。请帮我在hibernate中编写标准,因为我对此很陌生。

【问题讨论】:

  • 您不能使用TOP,因为这是 SQL Server 独有的,而 HQL 不支持。唯一的方法是创建一个独占的Query 并使用setMaxResults 方法。

标签: sql-server hibernate subquery hql hibernate-criteria


【解决方案1】:

第二个 Append 的内部子查询中的 Where 子句。 它应该是 terminal_Info_id 而不是 terminalInfo.id

final StringBuilder hql = new StringBuilder();
        hql.append(" from TerminalRemoteDeployment e");
        hql.append(" where e.id = (Select TOP 1 id from TerminalRemoteDeployment e1 where e1.terminal_Info_id = e.terminal_Info_id order by e1.version desc)");

        Query query = getEntityManager().createQuery(hql.toString());
        resultList = (List<TerminalRemoteDeployment>) query.getResultList();

【讨论】:

    【解决方案2】:

    正如评论中所说,使用setMaxResult() 方法而不是TOP 关键字,因为HQL 不支持它。

    同样在sub-select 中,您使用的id 没有实体别名。

    改成Select e1.id from TerminalRemoteDeployment e1

    【讨论】:

      【解决方案3】:

      首先,我不是 Hibernate 方面的专家。但是您的第一个查询是否特定于 SQL Server:

      select e.* 
      from terminal_remote_deployment e
      where id = (select top 1 e1.id
                  from terminal_remote_deployment e1
                  where e1.Terminal_info_id = e.Terminal_info_id
                  order by e1.version desc
                 );
      

      我会使用ROW_NUMBER(MySQL 8.0/MariaDB/SQL Server/PostgreSQL/Oracle/H2/Derby/...支持)重写它,然后我会使用命名查询:

      SELECT *
      FROM(SELECT e.*,
           ROW_NUMBER() OVER(PARTITION BY Terminal_info_id ORDER BY version desc) AS rn
           FROM terminal_remote_deployment e) sub
      WHERE rn = 1;
      

      【讨论】:

      • 这不是我的问题的确切答案,但是您的方法在休眠中编写子查询的需要减少了一些,它帮助我摆脱了编写子查询。我会接受答案。谢谢
      【解决方案4】:

      你要这样做吗?

      select e.* 
      from  terminal_remote_deployment e1 JOIN 
            (select e.id, max(e.version)
            from terminal_remote_deployment e group by e.id) as a
      on e.id = a.id
      

      【讨论】:

        猜你喜欢
        • 2012-04-01
        • 2013-06-07
        • 1970-01-01
        • 2013-07-21
        • 2013-07-13
        • 2015-10-10
        • 2016-12-05
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多