不与特定表关联的实体的命名查询

问题描述

我正在使用 Quarkus 和 Hibernate / Panache。

在本例中,我使用本机查询将 3 个表(table_atable_btable_c)连接在一起。在我正在进行的项目中,大约有 5 个 JOIN 表来检索我要查找的信息。

table_b 纯粹是 table_atable_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 类与它们各自的 @Table 以及它们的 @Column 名称进行了映射。我们在那个部门做得很好。

SELECT 
  a.id,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'

我只是在寻找 namelogin_date。在 table_atable_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 类;相反,它是一个对象数组 (List<Object[]>),其中包含我所有的 @Entities 以及我不想要的无关信息。

我迷路了。回到原生查询是否更有意义?

解决方法

您的 HQL 正在为结果中的每一行创建一个 Object[],因为您没有指定任何 SELECT,并且默认情况下 FROM 子句中的所有对象都包含在其中Object 数组。如果你想返回一个 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

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...