Я перевожу наш DAO с использования Hibernate Criteria API на JPA Criteria API.У меня там есть класс с несколькими @ManyToOne
:
@Entity
@Table(name = "A_TABLE", schema="SCHEMA_NAME")
public class A {
@ManyToOne
@JoinFormula("(SELECT * FROM (SELECT B.B_ID FROM SCHEMA_NAME.B_TABLE B WHERE B.A_ID = B_ID AND (B.B_CODE = '1' OR B.B_CODE = '2') ORDER BY B.B_CREATED_TIMESTAMP DESC) WHERE ROWNUM = 1)")
private B b1;
@ManyToOne
@JoinFormula("(SELECT * FROM (SELECT B.B_ID FROM SCHEMA_NAME.B_TABLE B WHERE B.A_ID = B_ID AND (B.B_CODE = '3' OR B.B_CODE = '4') ORDER BY B.B_CREATED_TIMESTAMP DESC) WHERE ROWNUM = 1)")
private B b2;
...
}
@Entity
@Table(name = "B_TABLE", schema="SCHEMA_NAME")
public class B {
}
В запросе я использую JoinType.LEFT
, чтобы избавиться от сгенерированных по умолчанию CROSS JOIN
s:
if (LEFT_OUTER_JOIN_ENTITIES.contains(field)) {
path = ((From) path).join(field, JoinType.LEFT);
} else {
path = path.get(field);
}
Я получаю правильные результаты, все записи A
и B
получены правильно.Однако после миграции у меня возникает проблема n + 1: все записи B
извлекаются одна за другой, несмотря на использование LEFT OUTER JOIN
в сгенерированных запросах.Ранее (при использовании Hibernate Criteria API) Hibernate мог выполнить запрос без n + 1 с такими же объединениями в сгенерированном SQL.
Спасибо за любые идеи и помощь!
ОБНОВЛЕНИЕ В качестве примера использования if-else
выше для поиска по "b1.fieldName" я получу следующее:
criteriaBuilder.equal(root.join("b1", JoinType.LEFT).get("someFiled"), 42)