Мне нужно выбрать основную таблицу и количество вхождений каждого статуса в другой таблице, используя критерии api только в одном запросе.
Мое текущее решение - это собственный запрос, который работает, но я хочу сделать это более объектно-ориентированным способом.
Я попытался сделать это в критериях, используя определенный запрос, просто чтобы выбрать все состояния, а затем посчитать его вручную. Но при таком подходе я вызываю два запроса: один для извлечения подробностей из моей основной таблицы, а другой для выбора всех состояний, где идентификатор совпадает с основной таблицей.
Есть ли более эффективный способ сделать это?
Вот мой родной запрос (упрощенный):
SELECT * FROM(
SELECT a.id, a.type, b.count_pending, b.count_failed, b.count_processed
FROM CM AS a
LEFT JOIN ( SELECT
COUNT( CASE WHEN status = 'PENDING' THEN 1 ELSE NULL END ) count_pending,
COUNT( CASE WHEN status = 'FAILED' THEN 1 ELSE NULL END ) count_failed,
COUNT( CASE WHEN status = 'PROCESSED' THEN 1 ELSE NULL END ) count_processed
FROM CM_PARAM WHERE id_cm = :cmId
GROUP BY id_cm
) AS b ON a.id_cm = b.id_cm
WHERE a.id_cm = :cmId) AS a
Вот моя сущность CM (упрощенно):
@Entity
public class Cm {
@Id
private Long idCm;
private String type;
// other fields
// setters and getters
}
Вот моя сущность CM_PARAM (упрощенно):
@Entity
public class CmParam {
@Id
private Long idCmp;
@ManyToOne
@JoinColumn(name = "id_cm")
private Cm cm;
private String status;
// other fields
// setters and getters
}
Используя собственный метод запросов, я могу добавить переходные поля в моей сущности Cm:
@Transient
private Long countPending;
@Transient
private Long countFailed;
@Transient
private Long countProcessed;
Как я могу это сделать, используя критерии api и, если возможно, всего за одну транзакцию.
Ожидаемый результат будет выглядеть примерно так:
{
"idCm": 1,
"type": "sms",
"countPending": 5,
"countFailed": 3,
"countProcessed": 9
}