Методы навигации в соединениях выборки критериев в JPA 2.1

При использовании соединений выборки в критериях JPA метод навигации не отображается. Ниже приведен пример.

Root<UserTable> root = criteriaQuery.from(entityManager.getMetamodel().entity(UserTable.class));
Fetch<UserTable, StateTable> fetch = root.fetch(UserTable_.stateTable, JoinType.INNER);

Чтобы перемещаться по рассматриваемому объекту, этот тип Fetch должен быть приведен к объединению, как показано ниже.

Join<UserTable, StateTable> join = (Join<UserTable, StateTable>) root.fetch(UserTable_.stateTable, JoinType.INNER);

Метод навигации get() доступен после этого приведения, например,

join.get(UserTable_.firstName);

Является ли этот тип приведения переносимым (пока он работает в EclipseLink (2.5.1) и Hibernate (4.3.5))? Есть ли другие способы сделать то же самое? Есть ли какая-либо конкретная причина, по которой соединения выборки критериев не поддерживают метод навигации?


ОБНОВЛЕНИЕ: (я все же считаю, что это всего лишь частичный ответ. Следовательно, не написано в разделе ответов)

Это очень хорошо видно на здесь от Джеймса о том, почему метод навигации в FETCH JOIN (включая псевдонимы в JPQL) крайне не рекомендуется и не рекомендуется, особенно в отношениях OneToMany (и, следовательно, не предоставляется/поддерживается напрямую в FETCH JOINs):

EclipseLink позволяет вам использовать псевдоним в файле JOIN FETCH. Эта поддержка была предназначена для отношений OneToOne и ManyToOne, чтобы избежать необходимости присоединяться к ней дважды только для получения псевдонима, а также разрешить использовать ее в ORDER BY или другими способами, которые не будут фильтровать результаты и изменять способ объекты строятся. Но ничто не мешает вам использовать его с OneToMany для фильтрации содержимого полученных OneToMany результатов.

Вместо этого вы можете прочитать весь блог с приведенными примерами. По моему опыту, Hibernate (в последних версиях) также позволяет нам это делать.

В общем, я лично не использую псевдонимы в отношениях OneToMany для навигации по целевому объекту (тот, у которого есть внешний ключ), который действительно не должен быть нужен в реальных проектах в лучшем случае, но требуется в OneToOne и/или ManyToOne.


person Tiny    schedule 08.06.2014    source источник
comment
все, что выходит за рамки спецификации, явно не переносимо по определению.   -  person Neil Stockton    schedule 09.06.2014
comment
Сам JPA CriteriaBuilder API из ада :)   -  person Tiny    schedule 09.06.2014


Ответы (1)


Вы можете позвонить

Join<UserTable, StateTable> join = root.join("prop", JoinType.INNER);

См. здесь: http://docs.oracle.com/javaee/6/api/javax/persistence/criteria/From.html#join%28java.lang.String,%20javax.persistence.criteria.JoinType%29

person win_wave    schedule 19.06.2014
comment
это делает соединение. Это не делает выборку. - person Neil Stockton; 19.06.2014
comment
root.join("prop", JoinType.INNER); не приводит к объединению выборки, как указано в предыдущем комментарии. - person Tiny; 19.06.2014