Иногда удобно извлечь из базы данные в вид Map. Например, если запрос содержит group by. Ниже рассмотрим, как это сделать.
Модель
Допустим, в таблице хранятся доходы — сумма дохода и дата дохода. Доходы относятся к разным годам, а мы хотим посчитать общую сумму дохода за каждый год.
Сущность Income, в которой хранятся доходы:
@Data
@NoArgsConstructor
@Entity
public class Income {
    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE)
    private long id;
    private LocalDate localDate;
    private int sum;
}
JPQL-запрос с group by
JPQL-запрос для получения общей суммы дохода по каждому году будет таким:
select year(i.localDate) as year, sum(i.sum) as sum from Income i group by year
Обычно Query возвращает List:
List<Tuple> list=em.createQuery("select year(i.localDate) as year, sum(i.sum) as sum from Income i group by year").getResultList();
Но нам надо получить Map. Есть несколько способов.
С помощью getResultStream()
Map<Integer, Integer> map=em.createQuery("select year(i.localDate) as year, sum(i.sum) as sum from Income i group by year", Tuple.class)
        .getResultStream()
        .collect(
                Collectors.toMap(
                        tuple -> ((Number) tuple.get("year")).intValue(),
                        tuple -> ((Number) tuple.get("sum")).intValue()
                )
        );
getResultList() в Stream
Либо ResultList преобразуем в Stream:
Map<Integer, Integer> map=em.createQuery("select year(i.localDate) as year, sum(i.sum) as sum from Income i group by year", Tuple.class)
        .getResultList()
        .stream()
        .collect(
                Collectors.toMap(
                        tuple -> ((Number) tuple.get("year")).intValue(),
                        tuple -> ((Number) tuple.get("sum")).intValue()
                )
        );
С помощью ResultTransformer из библиотеки
Есть также библиотека hibernate-types, в которой реализован специальный MapResultTransformer. Его тоже можно использовать:
Map<Integer, Integer> map= (Map<Integer, Integer>) em.createQuery("select year(i.localDate) as year, sum(i.sum) as sum from Income i group by year")
        .unwrap(org.hibernate.query.Query.class)
        .setResultTransformer(
                new MapResultTransformer<>()
        )
        .getSingleResult();
Другой пример реализации ResultTransformer рассмотрен в статье о получении проекций.
Исходный код
Исходный код примера есть на GitHub.