16

特定の日付以降にユーザーが作成されたフォルダーのすべてのユーザーを取得しようとしています。ユーザーとフォルダーの関係は、別のテーブルに存在します。

これは私が思いついたクエリですが、例外がスローされます

明示的な選択がなく、暗黙の 1 つのコールドが決定されない

コード

@Override
public List<RetailPostUserTbl> getNewUsersForSiteSince( Date date, Integer siteId )
{
    List<RetailPostUserTbl> toReturn = new ArrayList<RetailPostUserTbl>();
    EntityManager em = getEntityManager();
    CriteriaBuilder cb = em.getCriteriaBuilder();

    Class<RpUserFolderMapTbl> userFolderPC = userFolderMapDAO.getPersistentClass();

    CriteriaQuery<RpUserFolderMapTbl> mapQuery = cb.createQuery( userFolderPC );
    Root<RpUserFolderMapTbl> root = mapQuery.from( userFolderPC );
    Path<Integer> folderIdPath = root.get( RpUserFolderMapTbl_.folder ).get( FolderTbl_.folderId );

    Predicate folderCondition = cb.equal( folderIdPath, siteId );

    Subquery<RetailPostUserTbl> rpSubQ = mapQuery.subquery( persistentClass );
    Root<RetailPostUserTbl> subQRoot = rpSubQ.from( persistentClass );
    Path<UserTbl> userPath = subQRoot.get( RetailPostUserTbl_.user );
    Path<Date> userCreatedPath = userPath.get( UserTbl_.userCreateDate );
    Predicate userCreateDateCondition = cb.greaterThanOrEqualTo( userCreatedPath, date );
    rpSubQ.where( userCreateDateCondition );

    mapQuery.where( cb.and( folderCondition, cb.exists( rpSubQ ) ) );

    TypedQuery<RpUserFolderMapTbl> query = em.createQuery( mapQuery );
    List<RpUserFolderMapTbl> results = query.getResultList();
    for ( RpUserFolderMapTbl result : results )
    {
        RetailPostUserTbl rpuser = result.getUser().getRetailPostUser();
        toReturn.add( rpuser );
    }
    return toReturn;
}

これが機能しない理由を知っている人はいますか?

4

2 に答える 2

30

「サブクエリ」に対しても明示的に選択を設定する必要があります。

rpSubQ.select(subQRoot);
于 2014-09-16T08:46:58.183 に答える
8

今日、まったく同じエラーが発生しました。面白いことに、Hibernate 3.6.3.Final のドキュメントから例を引用しました。その例は次のとおりです。

CriteriaQuery query = builder.createQuery();
Root<Person> men = query.from( Person.class );
Root<Person> women = query.from( Person.class );
Predicate menRestriction = builder.and(
    builder.equal( men.get( Person_.gender ), Gender.MALE ),
    builder.equal( men.get( Person_.relationshipStatus ), RelationshipStatus.SINGLE )
);
Predicate womenRestriction = builder.and(
    builder.equal( women.get( Person_.gender ), Gender.FEMALE ),
    builder.equal( women.get( Person_.relationshipStatus ), RelationshipStatus.SINGLE )
);
query.where( builder.and( menRestriction, womenRestriction ) );

エラーを「修正」するために私がしたことは、ルートを明示的に選択することです。これを解決するには、1 つのルートを作成する必要があることに注意してください。これが私の例です:

CriteriaQuery query = builder.createQuery();
Root<Person> personRoot = query.from( Person.class );
Predicate menRestriction = builder.and(
    builder.equal( personRoot.get( Person_.gender ), Gender.MALE ),
    builder.equal( personRoot.get( Person_.relationshipStatus ), RelationshipStatus.SINGLE )
);
Predicate womenRestriction = builder.and(
    builder.equal( personRoot.get( Person_.gender ), Gender.FEMALE ),
    builder.equal( personRoot.get( Person_.relationshipStatus ), RelationshipStatus.SINGLE )
);
query.select(personRoot);
query.where( builder.and( menRestriction, womenRestriction ) );

私が理解できないのは、暗黙の選択ができなかった理由です。Hibernate の例では、使用される唯一のクラスはPerson.classです。もう少し掘り下げたら、応答を更新します。

于 2011-04-19T21:58:53.333 に答える