Как написать запрос JPA для заполнения объекта передачи данных (отличного от моего объекта @Entity)?

Мы используем Java 6, JPA 2.1 и Hibernate 4.3.6.Final. У меня есть приведенный ниже код, который находит объекты нашей организации…

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

Эти объекты Organization являются объектами, интенсивно использующими данные. У нас есть объект передачи данных OrganizationDto, который содержит только подмножество полей Organization. Есть ли способ настроить вышеперечисленное для заполнения объектов OrganizationDto вместо объектов Organization? Чего я хотел бы избежать, так это получения набора результатов, а затем написания цикла for, чтобы пройти через все это и создать все объекты передачи данных. Было бы здорово, если бы запрос мог как-то сразу заполнять эти объекты передачи данных.


person Dave    schedule 27.08.2015    source источник


Ответы (1)


Есть несколько примеров того, что называется выражением конструктора в спецификации JPA 2.1, которые позволяют запросу использовать любой конструктор pojo для возврата экземпляров. Конструктор должен принимать список выбора в качестве параметров. Один из примеров в спецификации, написанной с использованием JPQL:

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

будет создан с запросом типа как:

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

Если предположить, что существует конструктор для CustomerDetail, принимающий поля идентификатора, статуса и количества, то запрос вернет эти экземпляры вместо сущностей.

person Chris    schedule 28.08.2015