SQL 到 HQL 翻译问题
SQL To HQL translation issue
这是我的两个实体:
@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 查询写入表 1 中的 return 重复行,然后使用其他条件过滤结果。
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>.
如有任何帮助,我们将不胜感激。
在此先感谢您。
我只会使用 @NamedNativeQuery
而不会费心将相对复杂的查询转换为 HSQL。您仍然可以使用 setParameter
.
如果您确实需要使用 HSQL,我建议您 re-post 一个带有行号的代码版本,以便它们可以与错误消息相匹配。
我自己解决了这个问题。
请注意,sub select 是嵌入到另一个查询中的查询。这是 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)
这是我的两个实体:
@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 查询写入表 1 中的 return 重复行,然后使用其他条件过滤结果。
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>.
如有任何帮助,我们将不胜感激。 在此先感谢您。
我只会使用 @NamedNativeQuery
而不会费心将相对复杂的查询转换为 HSQL。您仍然可以使用 setParameter
.
如果您确实需要使用 HSQL,我建议您 re-post 一个带有行号的代码版本,以便它们可以与错误消息相匹配。
我自己解决了这个问题。 请注意,sub select 是嵌入到另一个查询中的查询。这是 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)