Собственные результаты запроса JPA 2.0 в виде карты - PullRequest
21 голосов
/ 29 сентября 2011

Я запускаю собственный запрос JPA 2.0 следующим образом:

Query query = em.createNativeQuery("SELECT NAME, SURNAME, AGE FROM PERSON");
List list = query.getResultList();

сейчас list содержит все строки, возвращаемые запросом. Я могу перебрать их, но каждая запись - это Object[], где:

  • по индексу 0 я нахожу ИМЯ
  • по индексу 1 я нахожу фамилию
  • в индексе 3 я нахожу ВОЗРАСТ

Кто-нибудь нашел способ сделать что-то вроде этого:

Map<String, Object> row = list.get(index);
String name = row.get("NAME");
String surname = row.get("SURNAME");
Integer age = row.get("AGE");

Мне это нужно, поскольку выполняемый мной собственный запрос является динамическим, и я не знаю порядок поля в предложении SELECT, поэтому я не знаю id, на который будет похож запрос:

SELECT SURNAME, NAME, AGE FROM PERSON

или

SELECT AGE, NAME, SURNAME FROM PERSON

или даже

SELECT AGE, SURNAME, NAME FROM PERSON

Ответы [ 3 ]

16 голосов
/ 30 октября 2011

Какой JPA вы используете - Hibernate, EclipseLink или что-то еще?

Нет стандартного способа сделать это в JPA, но ваша конкретная реализация может это позволить - например, Eclipselink имеет подсказку типа результата запроса.

http://dev.eclipse.org/mhonarc/lists/eclipselink-users/msg03013.html

Query query = entityManager.createNativeQuery(sql);
query.setHint(QueryHints.RESULT_TYPE, ResultType.Map);

Для Hibernate, с javax.persistence.Query dbQuery:

org.hibernate.Query hibernateQuery =((org.hibernate.jpa.HibernateQuery)dbQuery)
.getHibernateQuery();
hibernateQuery.setResultTransformer(AliasToEntityMapResultTransformer.INSTANCE);
3 голосов
/ 13 сентября 2017

Как уже упоминалось, более старый JPA не поддерживает его, однако в моей ситуации есть обходное решение с Postgres 9.4 при работе с Jackson,

List<String> list = em.createNativeQuery("select cast(json_object_agg(c.config_key,c.config_value) as text) from myschema.configuration c")
                   .getResultList();

Чтобы использовать его в слое Bean, используйте метод ниже, иначе вернитесь напрямую.

//handle exception here, this is just sample
Map map = new ObjectMapper().readValue(list.get(0), Map.class);

Еще несколько функций json, https://www.postgresql.org/docs/9.4/static/functions-json.html. Я уверен, что вы можете найти то же самое для других баз данных.

3 голосов
/ 24 апреля 2012

Посмотрите на это, я понял, когда работал над проектом, что я не мог использовать все функции JPA, поэтому я попробовал традиционный метод jdbc, даже если бы я не рекомендовал это, но он работает для меня.

@LocalBean
public class TCotisationEJB {

    @PersistenceContext(unitName="ClaimsProjectPU")
    private EntityManager em;

    @TransactionAttribute(TransactionAttributeType.NEVER)
    public List getCotisation(){
        Query query=em.createNativeQuery("select Annee,Mois,RetSonarwa from TCotisMIFOTRA2008 where matricule='10000493' order by Annee");
        List<Object[]> cotisation=query.getResultList();
        Object[] cotisationData;

         for(int i=0;i<cotisation.size();i++){
              cotisationData=cotisation.get(i);

             System.out.print("Annee: "+cotisationData[0]+" Mois :"+cotisationData[1]+" Amount       :"+cotisationData[2]+"\n");

     }  
     return query.getResultList();
     }    
}
...