【问题标题】:SQL To HQL translation issueSQL 到 HQL 转换问题
【发布时间】:2021-01-10 00:00:34
【问题描述】:

这是我的两个实体:

@Table(name = "Table1")
@Entity
public class Table1 {
private Long id;
private Table2 table2;
private String field2;

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "ID")
public Long getId() {
    return id;
}

public void setId(Long id) {
    this.id = id;
}

@ManyToOne(optional = false)
@JoinColumn(name = "field1")
public Table2 getTable2() {
    return table2;
}

public void setTable2(Table2 table2) {
    this.table2 = table2;
}

@Column(name = "field2")
public String getField2() {
    return field2;
}

public void setField2(String field2) {
    this.field2 = field2;
}
}

@Table(name = "table2")
@Entity
public class Table2 {
private Long id;
private List<Table1> table1List;
private String field5;
private boolean field4;
private String field3;

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "ID", insertable = false, updatable = false)
public Long getId() {
    return id;
}

public void setId(Long id) {
    this.id = id;
}

@OneToMany(mappedBy = "table2", cascade = CascadeType.ALL)
@LazyCollection(LazyCollectionOption.FALSE)
public List<Table1> getTable1List() {
    return table1lList;
}

public void setTable1List(List<Table1> table1List) {
    this.table1List = table1List;
}

@Column(name = "field5")
public String getField5() {
    return field5;
}

public void setField5(String field5) {
    this.field5 = field5;
}

@Column(name = "field4")
public boolean getField4() {
    return field4;
}

public void setField4(boolean field4) {
    this.field4 = field4;
}

@Column(name = "field3")
public String getField3() {
    return field3;
}

public void setField3(String field3) {
    this.field3 = field3;
}

}

我编写 SQL 查询以从 table1 返回重复的行,然后使用其他条件过滤结果。

SELECT p1.*
 FROM table1 p1, table2 d
  JOIN (
     SELECT field1, field2, COUNT(*)
       FROM table1
        GROUP BY field1, field2
         HAVING count(*) > 1 
     ) p2
  ON 
  p1.field1 = p2.field1 AND
  p1.field2 = p2.field2 and 
  d.id = p1.field1 and
  d.field3 IN ('A', 'B') and 
  d.field4 = 0 and
  d.field5 not in ('DD', 'MM', 'FF', 'RR')
ORDER BY p1.field2

我试图将我的查询翻译成 HQL:

SELECT p1 FROM Table1 p1, Table2 d 
  WHERE (p1.table2.id, p1.field1) in (
         SELECT table2.id, field2 FROM (
            SELECT pp.table2.id, pp.field2, COUNT(pp)
                FROM table1 pp
                GROUP BY pp.table2.id, pp.field2
                HAVING count(pp) > 1 
         )
        ) AND
        p.table2.id = d.id AND
        d.field3 IN (:list3) AND
        d.field4 = false AND
        d.field5 NOT IN (:list5)

运行我的应用程序时,我收到以下错误:

Sep 23, 2020 6:45:17 PM org.hibernate.hql.ast.ErrorCounter reportError
SEVERE: line 1:263: unexpected token: (
<Sep 23, 2020, 6:45:17,203 PM CEST> <Error> <org.hibernate.hql.PARSER> <BEA-000000> <line 1:263: unexpected token: (> 
Sep 23, 2020 6:45:17 PM org.hibernate.hql.ast.ErrorCounter reportError
SEVERE: line 1:308: unexpected token: COUNT
<Sep 23, 2020, 6:45:17,208 PM CEST> <Error> <org.hibernate.hql.PARSER> <BEA-000000> <line 1:308: unexpected token: COUNT> 
Sep 23, 2020 6:45:17 PM org.hibernate.hql.ast.ErrorCounter reportError
SEVERE: line 1:318: unexpected token: FROM
<Sep 23, 2020, 6:45:17,209 PM CEST> <Error> <org.hibernate.hql.PARSER> <BEA-000000> <line 1:318: unexpected token: FROM>.

任何帮助将不胜感激。 提前谢谢你。

【问题讨论】:

    标签: sql hibernate hql db2-luw


    【解决方案1】:

    我设法自己解决了这个问题。 请注意,子选择是嵌入到另一个查询中的查询。这是 SQL 的一个强大功能。不幸的是,JPQL 仅在 WHERE 子句中支持它,而不在 SELECT 或 FROM 子句中支持。

    调整后的 SQL 查询:

    SELECT p1.*
    FROM table1 p1, table2 d
    JOIN (
          SELECT field2
          FROM table1
          GROUP BY field2
          HAVING count(*) > 1 
         ) p2
    ON 
    p1.field2 = p2.field2
    and p1.field1 =  d.id
    and d.field3 IN ('A', 'B') 
    and d.field4 = 0
    and d.field5 not in ('DD', 'MM', 'FF', 'RR')
    ORDER BY p1.field2 
    

    稍微调整一下我的 SQL 查询后的最终可执行 HQL 查询是:

    SELECT p1 FROM Table1 p1, Table2 d 
    WHERE p1.field2 in (
              SELECT pp.field2
              FROM table1 pp
              GROUP BY pp.field2
              HAVING count(pp.field2) > 1 
          ) 
          AND p.table2.id = d.id
          AND d.field3 IN (:list3)
          AND d.field4 = false
          AND d.field5 NOT IN (:list5)
    

    【讨论】:

      【解决方案2】:

      我只会使用@NamedNativeQuery 而不会费心将相对复杂的查询转换为 HSQL。你仍然可以使用setParameter

      如果您确实需要使用 HSQL,我建议您重新发布带有行号的代码版本,以便它们与错误消息匹配。

      【讨论】:

      • 感谢您回答我的问题。是的,我必须使用 HSQL。
      • 好的。如果 HQL 除了你拥有的元组 IN 之外没有 (p1.table2.id, p1.field1) IN…,我不会感到惊讶。同样,HQL 并不是此类查询的最佳工具。因此,除非这是课堂作业,否则请使用本机。
      • HQL 在处理 IN (p1.table2.id, p1.field1) 方面没有任何问题..您需要做的所有事情都是使您的子查询返回您指定的相同数量的字段谓词 In(..)。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-09-06
      • 2021-06-14
      相关资源
      最近更新 更多