1

Мы используем Java 6, JPA 2.1 и Hibernate 4.3.6.Final. У меня есть код ниже, который находит наши объекты Организации ...Как написать запрос JPA для заполнения объекта передачи данных (отличного от моего объекта @Entity)?

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

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

ответ

2

Существует несколько примеров того, что называется выражением конструктора в спецификации 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 существует, чтобы взять в ID, статус и количество полей, то запрос вернет эти экземпляры вместо Entities.