Как я могу получить список объектов + дополнительное значение с JPA / Hibernate? - PullRequest
2 голосов
/ 07 января 2011

Есть две таблицы, report и 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 где-нибудь в моем Report объектном объекте. Как этого достичь?

Ответы [ 3 ]

2 голосов
/ 07 января 2011

Я думаю, что самым простым способом было бы создать временное поле в 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 голос
/ 07 января 2011
0 голосов
/ 07 января 2011

Я уверен, что есть ряд причин, по которым то, над чем вы работаете, не спроектировано таким образом. Вероятно, есть больше причин, по которым вы не хотите его переделывать. Я понимаю, что это может вообще не ответить на ваш вопрос, но если бы я был вами, и у меня было бы время, у меня была бы склонность сделать что-то вроде этого:

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();
}

То, что я предложил, предполагает, что вы работаете в веб-приложении и используете своего рода открытую сессию в поле зрения. В противном случае вам, вероятно, придется охотно получать эти комментарии, что может быть плохо.

Но, если вы собираетесь использовать Hibernate, почему бы не пойти немного дальше? Его цель - абстрагировать и скрыть код базы данных, и то, что я указал, является шагом в этом направлении.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...