如何获取 select 不同的结果作为实体列表而不是元组

How to obtain the result of a select distinct as an entity list instead of tuples

我正在编写一个 JSF 应用程序,它允许用户 select 文件夹列表中的文档列表,用户在其中单击特定文件夹 link 以查看与以下内容相关的文档列表selected 文件夹。

在尝试了传统的ORM方法后,我尝试定义了如下结果class:

 @SuppressWarnings("unchecked")
public List<ProjectDocs> findAllFolders(int projectid) {
    final String SQLCOMMAND
            = "SELECT DISTINCT d.classification, d.fk_projectdoc_id " + "FROM "
            + ProjectDocs.class.getSimpleName() + " d "
            + " WHERE d.fk_projectdoc_id = ?1";

    Query query = em.createQuery(SQLCOMMAND);
    query.setParameter(1, projectid);
    try {
      //  ListDataModel<ProjectDocs> lresults = new ListDataModel<ProjectDocs>(query.getResultList());
  List<ProjectDocs> lresults = query.getResultList();
        return lresults;
    } catch (Exception ex) {
        throw new RuntimeException("FAILED", ex);
    }
}

我的托管 bean class 是:

@ManagedProperty(value = "#{projBB}")
// @Model

private ProjectsBB projectBean;

 public String selectFolders() {

    projects = projectBean.getProjectList().getRowData();
    projectid = projects.getProjectid();
    projects.setProjectid(projectid);
    listModel = (ListDataModel<ProjectDocs>) getFolderBaseModel();
    return "ProDocsFolderList";

}


   public DataModel<ProjectDocs> getFolderBaseModel() {

    /* Check cache */
    if (this.folderBaseModel == null) {
        this.folderBaseModel= buildFolderListModel(this.projectid);
    }
    return this.folderBaseModel;
}

public DataModel<ProjectDocs> buildFolderListModel(int projectid) {
    List<ProjectDocs> folderList = proDocs.findFolderList(projectid);
    DataModel<ProjectDocs> model = new ListDataModel<ProjectDocs>(folderList);
    return model;
}

堆栈:

WARNING:   StandardWrapperValve[Faces Servlet]: Servlet.service() for servlet Faces Servlet threw exception
java.lang.NumberFormatException: For input string: "classification"
at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
at java.lang.Integer.parseInt(Integer.java:492)
at java.lang.Integer.parseInt(Integer.java:527)
at javax.el.ArrayELResolver.toInteger(ArrayELResolver.java:378)
at javax.el.ArrayELResolver.getValue(ArrayELResolver.java:198)
at com.sun.faces.el.DemuxCompositeELResolver._getValue(DemuxCompositeELResolver.java:176)....

我几乎可以肯定这是由于在我的 DAO class 中使用显式 Select 语句引起的(我正在 selecting 特定的实体字段而不是whole entiy),以便结果作为数组返回。

我想知道 1) 合适的结果 class 应该是什么样的? 2) 除了定义的结果 class 之外,我是否需要包含自定义转换 class?

更新:

我不能使用整个 ProjectDocs 实体,因为这只会生成一个文档列表,每个文档旁边都有文件夹名称。我只想查看不同的文件夹列表,因此我需要在 SELECT 语句

中明确 SELECT classification 和 projectid

提前致谢!

您说您想要列表,所以只需查询 ProjectDocs 而不是它们的字段:

String SQLCOMMAND
            = "SELECT DISTINCT d FROM "
            + ProjectDocs.class.getSimpleName() + " d "
            + " WHERE d.fk_projectdoc_id = ?1";

然后 query.getResultList() 将 return 匹配 ProjectDocs 的列表,您可能应该使用类型化查询,这样您就不需要转换:

TypedQuery<ProjectDocs> query = em.createQuery(SQLCOMMAND,ProjectDocs.class);

然后您可以在您的 JSF 站点上访问 ProjectDosc 的 classification 字段。

根据您当前的 sql,您注意到您只要求两个字段,因此结果是 Object[],第一个条目匹配类型 classification 第二个 ID(长?) .

如果需要,您可以定义一个仅具有这两个属性的 class,并将其用作结果的包装器,但通常您只使用整个 ProjectDocs bean。

public class Classification {
    String classification;
    long id;
    public Classification (String classification,long id) {
        this.Classification = classification;
        this.id = id;
    }
} 

String SQLCOMMAND
            = "SELECT new full.package.path.to.Classification( d.classification, d.fk_projectdoc_id) " + "FROM "
            + ProjectDocs.class.getSimpleName() + " d "
            + " WHERE d.fk_projectdoc_id = ?1";