不与特定关联的实体的命名查询 table
Named query for entity that does not associate with a specific table
我正在使用 Quarkus 和 Hibernate/Panache。
对于此示例,我有 3 个 table(table_a
、table_b
、table_c
),我使用本机查询将它们连接在一起。在我正在进行的项目中,大约需要 5 JOIN
table 秒来检索我要查找的信息。
table_b
纯粹是 table_a
和 table_c
:
的映射/连接 table
SELECT
a.id,
a.name,
c.login_date
FROM
table_a a
JOIN table_b b ON b.a_id = a.id
JOIN table_c c ON b.c_id = c.id
WHERE
c.login_date > '01-MAY-21'
我正在将以上内容移植到 HQL。我已经将我所有的 @Entity
classes 映射到它们各自的 @Table
,以及它们的 @Column
名称。我们在那个部门做得很好。
SELECT
a.id,
a.name,
c.loginDate
FROM
TableA a
JOIN TableA b ON b.aId = a.id
JOIN TableB c ON b.cId = c.id
WHERE
c.loginDate > '01-MAY-21'
我只是在寻找 name
和 login_date
。在 table_a
和 table_c
中存储了一堆其他信息,我不想用于此特定查询。所以我为此调用创建了一个实体:
@Entity
@IdClass(LoginDetailsPk.class)
@NamedQuery(
name = "LoginDetails.findFromDate",
query = "FROM TableA a " +
"JOIN TableA b ON b.aId = a.id " +
"JOIN TableB c ON b.cId = c.id " +
"WHERE c.loginDate > '01-MAY-21'"
)
public class LoginDetails extends PanacheEntityBase {
@Id
private int id;
@Id
private String name;
@Id
private String loginDate;
public static List<LoginDetails> findFromDate(String fromDate) {
// Eventually pass fromDate into find()
return find("#LoginDetails.findFromDate").list();
}
}
我很难理解 return
为何有效。当我调用 LoginDetails.findFromDate(...)
并将其存储在 List<LoginDetails>
中时,它工作正常。但是,当我尝试访问该列表时,出现 ClassCastException
错误。
List<LoginDetails> details = LoginDetails.findFromDate(null);
for(LoginDetails detail : details) { // <------ Throws a class cast exception
//...
}
调试后,我注意到 List
中存储的通用类型甚至不是我的 LoginDetails
class;相反,它是一个对象数组 (List<Object[]>
),包含我所有的 @Entities
和我不想要的无关信息。
我迷路了。回到本机查询是否更有意义?
您的 HQL 正在为结果中的每一行创建一个 Object[]
,因为您没有指定任何 SELECT
,默认情况下包含 FROM
子句中的所有对象在那个 Object
数组中。如果你想 return 一个 LoginDetails
对象,你需要创建一个具有所有属性的构造函数:
public LoginDetails(int id, String name, String loginDate) {
this.id = id;
this.name = name;
this.loginDate = loginDate;
}
然后将查询更改为:
query = "SELECT new LoginDetails(a.id, a.name, c.loginDate) "
"FROM TableA a " +
"JOIN TableA b ON b.aId = a.id " +
"JOIN TableB c ON b.cId = c.id " +
"WHERE c.loginDate > '01-MAY-21'"
见https://docs.jboss.org/hibernate/core/3.5/reference/en/html/queryhql.html#queryhql-select
我正在使用 Quarkus 和 Hibernate/Panache。
对于此示例,我有 3 个 table(table_a
、table_b
、table_c
),我使用本机查询将它们连接在一起。在我正在进行的项目中,大约需要 5 JOIN
table 秒来检索我要查找的信息。
table_b
纯粹是 table_a
和 table_c
:
SELECT
a.id,
a.name,
c.login_date
FROM
table_a a
JOIN table_b b ON b.a_id = a.id
JOIN table_c c ON b.c_id = c.id
WHERE
c.login_date > '01-MAY-21'
我正在将以上内容移植到 HQL。我已经将我所有的 @Entity
classes 映射到它们各自的 @Table
,以及它们的 @Column
名称。我们在那个部门做得很好。
SELECT
a.id,
a.name,
c.loginDate
FROM
TableA a
JOIN TableA b ON b.aId = a.id
JOIN TableB c ON b.cId = c.id
WHERE
c.loginDate > '01-MAY-21'
我只是在寻找 name
和 login_date
。在 table_a
和 table_c
中存储了一堆其他信息,我不想用于此特定查询。所以我为此调用创建了一个实体:
@Entity
@IdClass(LoginDetailsPk.class)
@NamedQuery(
name = "LoginDetails.findFromDate",
query = "FROM TableA a " +
"JOIN TableA b ON b.aId = a.id " +
"JOIN TableB c ON b.cId = c.id " +
"WHERE c.loginDate > '01-MAY-21'"
)
public class LoginDetails extends PanacheEntityBase {
@Id
private int id;
@Id
private String name;
@Id
private String loginDate;
public static List<LoginDetails> findFromDate(String fromDate) {
// Eventually pass fromDate into find()
return find("#LoginDetails.findFromDate").list();
}
}
我很难理解 return
为何有效。当我调用 LoginDetails.findFromDate(...)
并将其存储在 List<LoginDetails>
中时,它工作正常。但是,当我尝试访问该列表时,出现 ClassCastException
错误。
List<LoginDetails> details = LoginDetails.findFromDate(null);
for(LoginDetails detail : details) { // <------ Throws a class cast exception
//...
}
调试后,我注意到 List
中存储的通用类型甚至不是我的 LoginDetails
class;相反,它是一个对象数组 (List<Object[]>
),包含我所有的 @Entities
和我不想要的无关信息。
我迷路了。回到本机查询是否更有意义?
您的 HQL 正在为结果中的每一行创建一个 Object[]
,因为您没有指定任何 SELECT
,默认情况下包含 FROM
子句中的所有对象在那个 Object
数组中。如果你想 return 一个 LoginDetails
对象,你需要创建一个具有所有属性的构造函数:
public LoginDetails(int id, String name, String loginDate) {
this.id = id;
this.name = name;
this.loginDate = loginDate;
}
然后将查询更改为:
query = "SELECT new LoginDetails(a.id, a.name, c.loginDate) "
"FROM TableA a " +
"JOIN TableA b ON b.aId = a.id " +
"JOIN TableB c ON b.cId = c.id " +
"WHERE c.loginDate > '01-MAY-21'"
见https://docs.jboss.org/hibernate/core/3.5/reference/en/html/queryhql.html#queryhql-select