Запрос по критерию JPA 2 с гибернацией не удается соединиться слева
В моем приложении у меня есть роли, которые имеют разрешения, я использовал для этого:
Query query =
em.createQuery(
"SELECT distinct r FROM Role r left join fetch r.permissions "
+ "where r.domain = ? " + "order by r.createdOn ").setParameter(
1, domain);
return query.getResultList();
Но хотел более тонкий контроль над ленивыми инициализациями. Поэтому я пытаюсь это сделать, но это не работает, потому что соединение выполняется так, как если бы оно было внутренним объединением, не принося одну роль и ее разрешения, но один результат на строку и на разрешение тоже.
public List<Role> findAll()
{
CriteriaBuilder criteriaBuilder;
CriteriaQuery<Role> criteriaQuery;
Root<Role> queryRoot;
Order createdOnDesc;
TypedQuery<Role> typedQuery;
List<Role> roleResultList;
//initialize query system
criteriaBuilder = em.getCriteriaBuilder();
//select * from Role
criteriaQuery = criteriaBuilder.createQuery(Role.class);
queryRoot = criteriaQuery.from(Role.class);
//join permissions by default "LEFT"
//***THIS LINE IS FAILING*** ????
queryRoot.join(Role_.permissions);
//get query
typedQuery = em.createQuery(criteriaQuery);
//the steps below must be done to avoid lazy initialization exceptions
//in case we want to access the list at a later time
roleResultList = typedQuery.getResultList();
for (Role role : roleResultList)
{
role.getPermissionsList();
}
return roleResultList;
}
Любые мысли или идеи будут высоко оценены.
1 ответ
Мне немного непонятно, чего ты хочешь достичь, но, возможно, следование поможет в любом случае.
По умолчанию это внутреннее соединение, как сказано в API.
//join permissions by default "LEFT"
//***THIS LINE IS FAILING*** ????
queryRoot.join(Role_.permissions);
Если вам нужно что-то похожее на оригинальный запрос JPQL, это можно сделать с помощью fetch. Если вы хотите использовать левое (внешнее) соединение вместо этого, это можно сделать с помощью метода соединения, который принимает JoinType в качестве аргумента:
queryRoot.join(Role_.permissions, JoinType.LEFT);
Когда нужны разные результаты, тогда CriteriaQuery.distinct полезен.