How do I write a JPA query to populate a data transfer object (different than my @Entity object)?

我怕爱的太早我们不能终老 提交于 2019-12-23 01:53:14

问题


We’re using Java 6, JPA 2.1, and Hibernate 4.3.6.Final. I have the below code that finds our Organization objects …

    final CriteriaBuilder builder = entityManager.getCriteriaBuilder();
    final CriteriaQuery<Organization> criteria = builder.createQuery(Organization.class);
    final Root<Organization> root = criteria.from(Organization.class);

    final CriteriaQuery query = buildCriteriaQuery(builder, criteria, root, country, state, organizationTypes, parentOrg, zipCode);
    final TypedQuery<Organization> typedQuery = entityManager.createQuery(query);
    if (page != null && pageSize != null)
    {
        int first = (page - 1) * pageSize;
        typedQuery.setFirstResult(first);
        typedQuery.setMaxResults(pageSize);
    }   // if
    return typedQuery.getResultList();

These Organization objects are very data-intensive objects. We have a data transfer object, OrganizationDto, which only contains a subset of the fields of Organization. Is there a way to configure the above to populate the OrganizationDto objects instead of the Organization objects? What I would like to avoid is getting the result set and then writing a for loop to go through all of it and create all the data transfer objects. It would be great if the query could somehow just populate these data transfer objects right away.


回答1:


There are a few examples of what is called a constructor expression in the JPA 2.1 specification that allow the query to use any pojo's constructor to return instances. The constructor must take the select list as parameters. One the example in the spec written using JPQL:

"SELECT NEW com.acme.example.CustomerDetails(c.id, c.status, o.quantity)
FROM Customer c JOIN c.orders o
WHERE o.quantity > 100"

would be created with a type query as:

CriteriaQuery<CustomerDetails> q =
cb.createQuery(CustomerDetails.class);
Root<Customer> c = q.from(Customer.class);
Join<Customer, Order> o = c.join(Customer_.orders);
q.where(cb.gt(o.get(Order_.quantity), 100));
q.select(cb.construct(CustomerDetails.class,
 c.get(Customer_.id),
 c.get(Customer_.status),
 o.get(Order_.quantity)));

Assuming a constructor for CustomerDetail exists to take in the ID, status and quantity fields, then the query would return these instances instead of Entities.



来源:https://stackoverflow.com/questions/32254860/how-do-i-write-a-jpa-query-to-populate-a-data-transfer-object-different-than-my

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!