Маппинг агрегированных данных из Postgres в Java/Kotlin POJO класс

Как можно смаппить данные, полученные из Postgres с помощью агрегирующих функций (json_agg, jsonb_agg, json_build_object и прочих) в POJO объект или Spring-процекцию с помощью интерфейса?

Используемый стек: Kotlin, Spring Boot, Hibernate, Spring Data JPA.

Сущность для примера:

@Entity
class Book(
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    val id: Long,
    val name: String,
    val genre: String,
    val author: String
)

И сам native запрос в репозитории, имплементирующем PagingAndSortingRepository:

select b.genre, json_agg(b.*)
froom book b
where :name is null or b.name = :name
and :author is null or b.author = :author
group by genre
order by name

Я использую нативный запрос потому, что не нашел подходящих агрегирующих функций в JPQL.

Проблема заключается в том, что вытаскивая из БД сущности или их часть, проблем не возникает. Для первого иногда достаточно описать все в названии метода, для второго можно написать проекцию, вроде вот такой:

interface BookProjection {
    fun getName(): String
    fun getGenre(): String
}

и подставить в тип возвращаемого значения.

Однако, результат работы агрегирующей функции в Postgres никак не получается смаппить в коллекцию или хотя бы массив ни через проекции:

interface BookProjection {
    fun getGenre(): String
    fun getBooks(): List<Book>
}

ни через конструкторы классов прямо в запросе JPQL (@Query(value = """сам запрос""")) - всегда получаем ошибку No Dialect mapping for JDBC type: 1111.

Пробовал даже создавать кастомную сущность, которая содержала нужную мне модель данных, где над полями были указаны типы для Hibernare с помощью @Type(type = "jsonb") из библиотеки com.vladmihalcea:hibernate-types-55:2.12.1.

В итоге получилось лишь с помощью интерфейса-проекции смаппить результат работы json_agg() в строку, которая затем парсится в объект с помощью Gson. Что само по себе является костылем.

Прошу помощи в поиске готового решения, наверняка с таким сталкивались уже немало раз.


Ответы (1 шт):

Автор решения: Ruslan Masgutov

Можно написать свою реализацию метода репозитория с использованием jdbcTemplate и маппить ResultSet в свою dto

Кастомная реализация репозитория: https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#repositories.custom-implementations

→ Ссылка