Можно ли преобразовать запрос, присоединяющийся к подселекту, в JPQL? - PullRequest
1 голос
/ 16 февраля 2020

Принимая во внимание следующий собственный запрос SQL, содержащий соединение с подвыбором, есть ли способ преобразовать его в запрос JPQL (или, альтернативно, возможно ли отобразить это с помощью @SqlResultSetMapping так, чтобы у меня не было выполнить тысячи последующих запросов для заполнения моих объектов (скажем, в этом случае Foo содержит ссылку на один Bar и список Baz сущностей):

SELECT 
    foo.*, bar.*, baz.*
FROM
    foo
        INNER JOIN
    bar ON foo.bar_id = bar.id
        INNER JOIN
    baz ON bar.baz_id = baz.id
        INNER JOIN
    (SELECT 
        bar_id, MAX(some_int) ct
    FROM
        foo
    WHERE
        some_int <= 2
    GROUP BY bar_id) max_id ON max_id.bar_id = foo.bar_id
WHERE
    foo.some_int = max_id.ct;

1 Ответ

1 голос
/ 17 февраля 2020

Не напрямую с JPQL, но вы можете использовать Blaze-Persistence поверх Hibernate для этого. См. Следующий пример: https://persistence.blazebit.com/documentation/1.5/core/manual/en_US/#subquery -in-from-clause

Я предполагаю модель JPA здесь для примера. Вам понадобится следующая сущность CTE.

@CTE
@Entity
public class MyMaxEntity {
  @Id Integer id;
  Integer someInt;
}

Это запрос

criteriaBuilderFactory.create(entityManager, Foo.class, "foo")
  .fetch("bar.baz")
  .innerJoinOnSubquery(MyMaxEntity.class, "maxEnt")
    .from(Foo.class, "subFoo")
    .bind("id").select("subFoo.id")
    .bind("value").select("MAX(subFoo.someInt)")
    .where("subFoo.someInt").le(2)
  .end()
    .on("maxEnt.id").eqExpression("foo.bar.id")
  .end()
  .where("foo.someInt").eqExpression("maxEnt.value")
...