我只想选择特定的列(例如SELECT a FROM b)。我有一个通用的DAO,我想到的是:
SELECT a FROM b
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。
The method select(Selection<? extends T>) in the type CriteriaQuery<T> is not applicable for the arguments (Path<Object>)
T
ID
VERSION
null
类型T扩展AbstractEntity有两个字段。
AbstractEntity
entityClazz是T.class。
entityClazz
T.class
仅获取特定列的JPA方法之一是请求一个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
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();
请参阅此链接以获取更多参考。