2011-01-07 47 views
2

有两个表格,报告和报告评论。每个报告评论都是通过外键分配给报告的,因此报告具有零到多个报告评论。
如果我需要一个列表,这给了我与每一份报告的评论中的相应号码的所有报告,我会做以下(含SQL):我如何检索entite + JPA/Hibernate的附加值列表?

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来获取这样的列表/休眠并将c.cnt存储在我的Report实体对象中。 这怎么可能实现?

回答

2

我觉得simpliest的办法是在Report创建一个短暂的领域,并通过转换相应的查询manully返回的元组,这样的事情:

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); 
} 
+0

看起来很有前途 - 我会尽力的! – Zeemee 2011-01-10 07:58:36

0

我敢肯定有很多的原因,什么你的工作是不是这样设计的。可能有更多原因让你不想重新设计它。我知道这可能不是回答你的问题在所有的,但如果我是你,我有时间,我不得不倾斜度,使这样的事情:

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应用程序中工作,并正在使用某种开放会话的视图。否则,你可能不得不热切地提取那些可能不好的评论。

但是,如果你打算使用休眠,为什么不去更进一步?它的目的是抽象和隐藏数据库代码,我所提供的是朝这个方向迈出的一步。

+0

zmf,你的方法当然是最明显的方法,如果我的例子不会被简化:)。现实是,没有“报告评论”,子选择本身返回“报告”。我不想要一个持久的关系。 但无论如何感谢您的补充。 – Zeemee 2011-01-10 06:39:38