JPA & Criteria API - select only specific columns

I would like to select only certain columns (e.g. SELECT a FROM b ). I have a generic DAO and I came up with the following:

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

And the error: The method select(Selection<? extends T>) in the type CriteriaQuery<T> is not applicable for the arguments (Path<Object>) . How can I change this? I want to get an object of type T that has only ID and VERSION fields, and all the rest are null .

Type T extends AbstractEntity , which has these 2 fields.

entityClazz T.class .

+41
java hibernate jpa criteria-api
Sep 27 '12 at 9:44
source share
3 answers

One way JPA can retrieve only specific columns is to request a Tuple object.

In your case, you need to write something like this:

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

Another approach is possible if you have a class representing the result, for example T in your case. T does not have to be an Entity class. If T has a constructor like:

 public T(Long id, Long version) 

then you can use T directly in your CriteriaQuery constructor:

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

See the link for more details.

+56
Oct 03 '12 at 5:35
source share
 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

+7
Mar 26 '14 at 23:14
source share

First of all, I don’t understand why you want the object to have only ID and version, and all other details should be zeros. However, here is some code that will do this for you (which does not use JPA Em, but normal Hibernate. I assume you can find equivalence in JPA or just get the Hibernate Session from em delegate Access the Hibernate session from EJB using EntityManager ):

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

This will return a list of objects for which their identifier and version are installed, and all other details are equal to zero, because the aliasToBean transformer will not be able to find them. Again, I'm not sure I can think of a situation in which I would like to do this.

+2
Sep 27 '12 at 10:59
source share



All Articles