Обработка вложенных коллекций с помощью собственного SQL или JPQL

#java #sql #postgresql #hibernate #jpql

Вопрос:

В данный момент я работаю над большим проектом, используя Hibernate (версия 5.3.10) и Spring Boot (версия 2.1.6). База данных-это Postgres 11. В качестве примера предположим, что у меня есть три сущности A, B и C.

Сущность A содержит множество объектов с B. B содержит одно целое с C.

Сущность A содержит ряд значений. Сущность B содержит столбец месяца и года и другие значения. Сущность C также содержит ряд значений.

Мне нужно выбрать все сущности A и включить только B (и вложенные в него сущности C) таким образом, чтобы год и месяц приходились на определенный финансовый год и квартал. Я могу легко сделать это в SQL с помощью чего-то вроде:

 SELECT * FROM a_table AS a  LEFT JOIN b_table AS b   ON a.a_id = b.a_id AND b.year = 2021 AND calculate_quarter(b.month) = 4  LEFT JOIN c_table AS c ON b.b_id = c.b_id;  

Но Hibernate, похоже, действительно борется с этим в JPQL. Это достаточно легко перевести с родного SQL:

 SELECT a FROM EntityA AS a  LEFT JOIN EntityB AS b   ON a.id = b.parent.id AND b.year = 2021 AND FUNCTION('calculate_quarter', b.month) = 4  LEFT JOIN EntityC AS c ON b.id = c.parent.id;  

Однако приведенный выше JPQL не ограничивает по годам и кварталам. Он извлекает все сущности A независимо от этого. Число сущностей B, связанных с A, также будет постоянно расти со временем, поэтому JPQL будет бороться, если он будет извлекать все, как это.

Есть ли какой-либо способ заставить JPQL выбрать все сущности и соблюдать ограничения, налагаемые левым соединением, или есть способ сопоставить эти вложенные коллекции сущностей с собственным SQL?