82

特定の列のみを選択したい (例SELECT a FROM b)。私は一般的なDAOを持っており、思いついたのは次のとおりです。

public List<T> getAll(boolean idAndVersionOnly) {
    CriteriaBuilder builder = manager.getCriteriaBuilder();
    CriteriaQuery<T> criteria = builder.createQuery(entityClazz);
    Root<T> root = criteria.from(entityClazz);
    if (idAndVersionOnly) {
        criteria.select(root.get("ID").get("VERSION")); // HERE IS ERROR
    } else {
        criteria.select(root);
    }
    return manager.createQuery(criteria).getResultList();
}

エラーは次のとおり The method select(Selection<? extends T>) in the type CriteriaQuery<T> is not applicable for the arguments (Path<Object>)です。どうすればそれを変更できますか? とフィールドのみを持ち、他のすべてが である型Tオブジェクトを取得したいと考えています。IDVERSIONnull

これらの 2 つのフィールドを持つextendsを入力しTますAbstractEntity

entityClazzですT.class

4

4 に答える 4

104

特定の列のみを取得する JPA の方法の 1 つは、Tupleオブジェクトを要求することです。

あなたの場合、次のように書く必要があります。

CriteriaQuery<Tuple> cq = builder.createTupleQuery();
// write the Root, Path elements as usual
Root<EntityClazz> root = cq.from(EntityClazz.class);
cq.multiselect(root.get(EntityClazz_.ID), root.get(EntityClazz_.VERSION));  //using metamodel
List<Tuple> tupleResult = em.createQuery(cq).getResultList();
for (Tuple t : tupleResult) {
    Long id = (Long) t.get(0);
    Long version = (Long) t.get(1);
}

あなたの場合のように、結果を表すクラスがある場合は、別のアプローチが可能ですTTEntity クラスである必要はありません。T次のようなコンストラクタがある場合:

public T(Long id, Long version)

次に、コンストラクターTで直接使用できます。CriteriaQuery

CriteriaQuery<T> cq = builder.createQuery(T.class);
// write the Root, Path elements as usual
Root<EntityClazz> root = cq.from(EntityClazz.class);
cq.multiselect(root.get(EntityClazz_.ID), root.get(EntityClazz_.VERSION));  //using metamodel
List<T> result = em.createQuery(cq).getResultList();

詳細については、このリンクを参照してください。

于 2012-10-03T05:35:17.833 に答える
12
cq.select(cb.construct(entityClazz.class, root.get("ID"), root.get("VERSION")));  // HERE IS NO ERROR

https://wiki.eclipse.org/EclipseLink/UserGuide/JPA/Basic_JPA_Development/Querying/Criteria#Constructors

于 2014-03-26T23:14:51.433 に答える
3

まず第一に、オブジェクトに ID とバージョンのみを持たせ、他のすべての小道具を null にする理由がよくわかりません。ただし、これを行うコードがいくつかあります (JPA Em を使用しませんが、通常の Hibernate を使用します。JPA で同等のものを見つけるか、単に em デリゲートから Hibernate Session obj を取得できると思います EJB から Hibernate Session にアクセスする) EntityManager を使用 ):

List<T> results = session.createCriteria(entityClazz)
    .setProjection( Projections.projectionList()
        .add( Property.forName("ID") )
        .add( Property.forName("VERSION") )
    )
    .setResultTransformer(Transformers.aliasToBean(entityClazz); 
    .list();

これにより、ID とバージョンが設定されたオブジェクトのリストと、他のすべての小道具が null に返されます。これは、aliasToBean トランスフォーマーがそれらを見つけることができないためです。繰り返しますが、私はそれをしたい状況を思いつくことができるかどうか確信が持てません.

于 2012-09-27T10:59:13.607 に答える