有两个表格,报告和报告评论。每个reportcomment都会(通过外键)分配给报告,因此报告中包含零到多个reportcomments 如果我需要一个列表,这会给我所有报告以及每个报告的相应评论数量,我会执行以下操作(使用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
存储在我的Report
实体对象中。
怎么可能实现呢?
答案 0 :(得分:2)
我认为最简单的方法是在Report
中创建一个瞬态字段并手动转换由相应查询返回的元组,如下所示:
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);
}
答案 1 :(得分:1)
我相信@SqlResultSetMapping可能适合你。
http://download.oracle.com/javaee/5/api/javax/persistence/SqlResultSetMapping.html
http://blogs.oracle.com/JPQL01/entry/native_query_in_java_persistence
答案 2 :(得分: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应用程序并正在使用某种开放式会话。否则你可能不得不急切地获取那些可能不好的评论。
但是,如果你打算使用hibernate,为什么不再进一步了?它的全部目的是抽象和隐藏数据库代码,我所提供的是朝这个方向迈出的一步。