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只有IDVERSION字段的类型对象,而所有其他都是null.

类型TextendsAbstractEntity具有这两个字段。

entityClazzT.class

4

4 回答 4

104

仅获取特定列的 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不需要是实体类。如果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 和版本的对象,而所有其他道具都是空值。但是,这里有一些代码可以为您做到这一点(它不使用 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 回答
-3

你可以做这样的事情

Session session = app.factory.openSession();
CriteriaBuilder builder = session.getCriteriaBuilder();
CriteriaQuery query = builder.createQuery();
Root<Users> root = query.from(Users.class);
query.select(root.get("firstname"));
String name = session.createQuery(query).getSingleResult();

您可以在其中将“名字”更改为所需列的名称。

于 2018-12-28T18:00:52.097 回答