特定の列(例: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
フィールドとID
フィールドのみを持つタイプVERSION
オブジェクトを取得したいのですが、他のすべてはnull
です。
タイプT
は、これらの2つのフィールドを持つAbstractEntity
を拡張します。
entityClazz
はT.class
です。
特定の列のみを取得する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);
}
T
のような結果を表すクラスがある場合、別のアプローチが可能です。 T
はEntityクラスである必要はありません。 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();
これを参照してください link 詳細については。
cq.select(cb.construct(entityClazz.class, root.get("ID"), root.get("VERSION"))); // HERE IS NO ERROR
まず、IDとバージョンのみを持ち、他のすべての小道具をnullにするオブジェクトが必要な理由がわかりません。ただし、これを行うコードがあります(JPA Emは使用せず、通常のHibernateを使用します。JPAで同等のものを見つけるか、emデリゲートからHibernate Session objを取得できると仮定します Accessing EntityManagerを使用したEJBからのHibernate Session ):
List<T> results = session.createCriteria(entityClazz)
.setProjection( Projections.projectionList()
.add( Property.forName("ID") )
.add( Property.forName("VERSION") )
)
.setResultTransformer(Transformers.aliasToBean(entityClazz);
.list();
AliasToBeanトランスフォーマーがそれらを見つけることができないので、これは、IDとバージョンが設定されたオブジェクトのリストと、他のすべてのプロパティをnullに返します。繰り返しますが、私はそれをしたい状況を考えることができるかどうかはわかりません。