1. ホーム
  2. java

[解決済み] JPA と Criteria API - 特定のカラムのみを選択する

2023-06-16 10:46:22

質問

特定のカラムだけを選択したい(例. 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 オブジェクトを取得したい。 IDVERSION フィールドがあり、その他はすべて null .

タイプ T 拡張 AbstractEntity を継承しており、この2つのフィールドを持っています。

entityClazzT.class .

どのように解決するのですか?

特定のカラムだけを取得するJPAの方法のひとつは、カラムを取得するために タプル オブジェクトを求めることです。

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

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

これを見る リンク を参照してください。