Я думаю, что то, что вы пытаетесь сделать, не выполнимо ... Даже если бы это было так, я бы не рекомендовал это ...
Цель ORM (Object Relational Mapping) состоит в том, чтобы сопоставить ваш код java с чем-то, что может понять реляционная база данных. По сути, вы можете перевести столбец таблицы в атрибут класса.
Здесь вы пытаетесь сделать что-то более сложное: вы отображаете содержимое запроса с помощью агрегатной функции (count) в java объект ... но столбца для отображения нет.
Я думаю, что вы испытываете то, что я называю «синдромом после травмы c JPA»: в основном вы думаете, что JPA будет править миром, и вы не видите смысла в написании SQL запроса сами , У вас аллергия от c до SQL :)
В вашем случае вы отображаете не таблицу, а результат запроса. Это не то, для чего создан ORM.
Вот 2 решения.
Запрос + JPA, отображающий вашу таблицу
Ваш TxnRejectDTO
не отображает одну таблицу, поэтому Вы должны оставить аннотации. Вы можете создать другой объект, который отображает таблицу "TXN_RESP_PRICE_REJECT": TxnRespProceReject
. Примерно так:
@Entity
@Table(name = "txn_resp_price_reject")
public class TxnRespPriceReject {
@Id
private String rejectCd;
private String aColumn;
public TxnRespPriceReject() {
}
// generate setters and getters
}
И создайте репозиторий для доступа к вашим данным. Spring сможет "привязать" ваш Repository
к вашему Entity
. И в этом, добавьте ваш запрос для получения вашего TxnRejectDTO
:
public interface TxnRejectPriceRejectRepository extends CrudRepository< TxnRespPriceReject, Long> {
@Query("SELECT new your.package.TxnRejectDTO(rejectCd, count(t)) FROM TxnRejectPriceReject t GROUP BY t.rejectCd")
public List<TxnRejectDTO> findTxnReject();
}
Обратите внимание на использование полного имени для конструктора (с пакетом). А пока сделайте TxnRejectDTO
простым компонентом, удалив аннотацию, связанную с Hibernate, с помощью конструктора all args.
public class TxnRejectDTO {
private String rejectCd;
private String count;
public TxnRejectDTO(String rejectCd, Long count) {
this.rejectCd = rejectCd;
this.count = count;
}
}
Это должно сделать это ... Но не уверен, что это именно то, что вам нужно. Вот хорошая ссылка: Как вернуть пользовательский объект из запроса Spring Data JPA GROUP BY
JPA без QUERY
Итак, если вы действительно стали аллергиками c в SQL в вашем java коде, почему вы не используете представление?
- Создать представление в вашей базе данных
CREATE VIEW txn_reject AS SELECT reject_id, count(1) as count from TXN_RESP_PRICE_REJECT rej GROUP BY rej.reject_cd FETCH FIRST 10 ROWS ONLY
Сопоставьте
TxnRejectDTO
с вашим представлением
@Entity
@Table(name = "txn_reject")
@Immutable // To let Spring know it won't need to update it (lighter, no cache...)
public class TxnRejectDTO {
@Id
private String rejectCd;
private String count;
public TxnRejectDTO() {
}
}
И затем объявите репозиторий для доступа к вашей сущности:
public interface TxnRejectDTORepository extends CrudRepository<TxnRejectDTO, Long> {
// the method findAll is provided, so you can get everything you need.
}
Вот ссылка на это решение: https://thoughts-on-java.org/hibernate-tips-map-view-hibernate/
Надеюсь, это поможет!