如何使用JPA/Hibernate检索Entite+附加值列表?

如何使用JPA/Hibernate检索Entite+附加值列表?,hibernate,jpa,Hibernate,Jpa,有两个表,report和reportcomment。每个reportcomment都是通过外键分配给报表的,因此报表具有零到多个reportcomment。 如果我需要一个列表,该列表为我提供了所有报告以及每个报告的注释数,我将使用SQL执行以下操作: SELECT r.*, c.cnt FROM report r LEFT JOIN ( SELECT ir.id AS report_id, COUNT(ic.id) AS cnt FROM report ir INNER

有两个表,report和reportcomment。每个reportcomment都是通过外键分配给报表的,因此报表具有零到多个reportcomment。 如果我需要一个列表,该列表为我提供了所有报告以及每个报告的注释数,我将使用SQL执行以下操作:

SELECT r.*, c.cnt
FROM report r
LEFT JOIN (
    SELECT ir.id AS report_id, COUNT(ic.id) AS cnt
    FROM report ir
    INNER JOIN reportcomment ic ON ir.id = ic.report_id
    GROUP BY ir.id
) c ON c.report_id = r.id
我想用JPA/Hibernate检索这样一个列表,并将c.cnt存储在我的报表实体对象中的某个位置。
如何实现这一点?

我认为最简单的方法是在报表中创建一个临时字段,并手动转换相应查询返回的元组,如下所示:

List<Object[]> tuples = em.createQuery(
    "SELECT r, COUNT(c) " +
    "FROM ReportComment c RIGHT JOIN c.report r" +
    "GROUP BY r.id, ...").getResultList();

List<Report> reports = new ArrayList<Report>();
for (Object[] tuple: tuples) {
    Report r = (Report) tuple[0];
    r.setCommentCount((Long) tuple[1]);
    reports.add(r);
}
public class Comment { 
...
List<CommentReport> commentReports = new ArrayList<CommentReport>();

@OneToMany(mappedBy="comment")
public List<CommentReports> getCommentReports() {
    return commentReports;
}

public void setCommentReports(List<CommentReport> commentReports) {
    this.commentReports = commentReports;
}

@Transient
public int countReports() {
    return commentReports.size();
}

我相信@SQLResultsMapping可能适合您


我相信有很多原因导致你的工作不是这样设计的。您不想重新设计它的原因可能更多。我意识到这可能根本不能回答你的问题,但如果我是你,我有时间,我会倾向于做这样的事情:

List<Object[]> tuples = em.createQuery(
    "SELECT r, COUNT(c) " +
    "FROM ReportComment c RIGHT JOIN c.report r" +
    "GROUP BY r.id, ...").getResultList();

List<Report> reports = new ArrayList<Report>();
for (Object[] tuple: tuples) {
    Report r = (Report) tuple[0];
    r.setCommentCount((Long) tuple[1]);
    reports.add(r);
}
public class Comment { 
...
List<CommentReport> commentReports = new ArrayList<CommentReport>();

@OneToMany(mappedBy="comment")
public List<CommentReports> getCommentReports() {
    return commentReports;
}

public void setCommentReports(List<CommentReport> commentReports) {
    this.commentReports = commentReports;
}

@Transient
public int countReports() {
    return commentReports.size();
}
我的建议假设您在web应用程序中工作,并且在视图中使用某种开放会话。否则,您可能不得不急切地获取这些评论,这可能是不好的


但是,如果您要使用hibernate,为什么不更进一步呢?它的全部目的是抽象和隐藏数据库代码,我提供的是朝着这个方向迈出的一步

zmf,如果我的示例不简化的话,您的方法当然是最明显的方法:。事实是,没有“reportcomment”,子选择返回“report”本身。我不想为此建立持久的关系。但无论如何,谢谢你的补充。谢谢你,乔尔,情况可能确实如此。我看到了这两页,但无法将其应用于我的问题…这看起来很有希望-我会试试看!