Использование JPA 2.0. По-видимому, по умолчанию (без явной выборки) поля @OneToOne(fetch = FetchType.EAGER)
выбираются в 1 + N запросах, где N - количество результатов, содержащих объект, который определяет отношение к отдельному связанному объекту. Используя API критериев, я могу попытаться избежать этого следующим образом:
CriteriaBuilder builder = entityManager.getCriteriaBuilder();
CriteriaQuery<MyEntity> query = builder.createQuery(MyEntity.class);
Root<MyEntity> root = query.from(MyEntity.class);
Join<MyEntity, RelatedEntity> join = root.join("relatedEntity");
root.fetch("relatedEntity");
query.select(root).where(builder.equals(join.get("id"), 3));
В идеале это должно быть эквивалентно следующему:
SELECT m FROM MyEntity m JOIN FETCH myEntity.relatedEntity r WHERE r.id = 3
Однако запрос критериев приводит к тому, что корневая таблица без необходимости соединяется с таблицей связанных сущностей дважды; один раз для извлечения и один раз для предиката. Полученный SQL выглядит примерно так:
SELECT myentity.id, myentity.attribute, relatedentity2.id, relatedentity2.attribute
FROM my_entity myentity
INNER JOIN related_entity relatedentity1 ON myentity.related_id = relatedentity1.id
INNER JOIN related_entity relatedentity2 ON myentity.related_id = relatedentity2.id
WHERE relatedentity1.id = 3
Увы, если я только делаю выборку, то у меня нет выражения для использования в предложении where.
Я что-то упустил, или это ограничение API критериев? Если это последнее, исправляется ли это в JPA 2.1 или существуют ли какие-либо улучшения для конкретного поставщика?
В противном случае, кажется, лучше просто отказаться от проверки типа компиляции (я понимаю, что мой пример не использует метамодель) и использует динамический JPQL TypedQueries.