简体   繁体   中英

JPA 2 criteria query with hibernate fails to left join

In my application I have Roles which have Permissions, I used to do this:

   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();

But wanted finer control over lazy initializations. So I am trying this but it is not working because the join is executing as if it was an inner join, not bringing one role and its permissions but one result per row and per permission too.

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;
}

Any thoughts or ideas will be highly appreciated.

It is little bit unclear to me what you want to achieve, but maybe following helps anyway.

This is by default inner join, as told also in API .

//join permissions by default "LEFT"
//***THIS LINE IS FAILING*** ????
queryRoot.join(Role_.permissions);

If you need something similar to original JPQL query, that can be done with fetch . If you want to use left (outer) join instead, that can be done with join method that takes JoinType as argument:

queryRoot.join(Role_.permissions, JoinType.LEFT);

When distinct results are needed, then CriteriaQuery.distinct is useful.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM