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

しかし、遅延初期化をより細かく制御したいと考えていました。だから私はこれを試していますが、結合が内部結合であるかのように実行され、1 つのロールとその権限をもたらすのではなく、行ごとおよび権限ごとに 1 つの結果ももたらすため、機能しません。

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

どんな考えやアイデアも高く評価されます。

4

1 に答える 1

1

あなたが達成したいことは私には少し不明確ですが、とにかく次のことが役立つかもしれません。

APIにも記載されているように、これはデフォルトで内部結合です。

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

元の JPQL クエリに似たものが必要な場合は、fetchで実行できます。代わりに左 (外部) 結合を使用する場合は、引数としてJoinTypeを取るjoinメソッドを使用して実行できます。

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

個別の結果が必要な場合は、CriteriaQuery.distinctが役立ちます。

于 2012-07-11T08:35:26.073 に答える