JPA Query.getResultList () - utiliser de manière générique

je crée une requête complexe avec plusieurs tables et j'ai besoin d'énumérer le résultat. Habituellement, je suis en utilisant le EntityManager et la carte le résultat de la JPA-Représentation:

UserEntity user = em.find(UserEntity.class, "5");

Ensuite, je peux accéder à toutes les valeurs que l'utilisateur UserEntity classe définit. Mais comment puis-je accéder aux valeurs de champ retournées à partir d'une requête native multi-tables? Ce que je reçois est une Liste d'Objets. C'est bien pour l'instant, mais quel est cet objet? Tableau? Carte? Collection? ...

//simpleExample
Query query = em.createNativeQuery("SELECT u.name,s.something FROM user u, someTable s WHERE s.user_id = u.id");
List list = query.getResultList();

//do sth. with the list, for example access "something" for every result row.

je suppose que le la réponse est assez simple, mais la plupart des exemples là-bas montrent juste l'usage lors du moulage direct à une classe de Target.

PS: dans l'exemple je pourrais utiliser les classes-mappings bien sûr. Mais dans mon cas someTable n'est pas géré par JPA, et par conséquent je n'ai pas l'entity ni une représentation de classe de celui-ci, et puisque je joins comme 20 tables, Je ne veux pas créer toutes les classes juste pour accéder aux valeurs.

23
demandé sur Roman C 2012-12-04 14:16:07

5 réponses

règle Générale est la suivante:

  • Si select contient une seule expression et c'est une entity, alors le résultat est cette entity
  • Si select contient une seule expression et c'est une primitive, alors le résultat est que primitive
  • Si select contient des expressions multiples, alors le résultat est Object[] contenant les primitives/entités correspondantes

Donc, dans votre cas list est un List<Object[]>.

51
répondu axtavt 2012-12-04 10:37:55
TypedQuery peut être utilisé:

TypedQuery<SimpleEntity> q = 
        em.createQuery("select t from SimpleEntity t", SimpleEntity.class);

List<SimpleEntity> listOfSimpleEntities = q.getResultList();
for (SimpleEntity entity : listOfSimpleEntities) {
    // do something useful with entity;
}
31
répondu gprest 2014-01-25 18:39:43

la requête ci-dessus renvoie la liste des objets[]. Donc si tu veux avoir le U. nom et art. quelque chose de la liste alors vous devez itérer et lancer ces valeurs pour les classes correspondantes.

8
répondu MGPJ 2012-12-04 10:33:03

si vous avez besoin d'un moyen plus pratique pour accéder aux résultats, il est possible de transformer le résultat d'une requête SQL arbitrairement complexe en une classe Java avec un minimum de tracas:

Query query = em.createNativeQuery("select 42 as age, 'Bob' as name from dual", 
        MyTest.class);
MyTest myTest = (MyTest) query.getResultList().get(0);
assertEquals("Bob", myTest.name);

la classe doit être déclarée @Entity, ce qui signifie que vous devez vous assurer qu'elle a un @Id unique.

@Entity
class MyTest {
    @Id String name;
    int age;
}
6
répondu GFonte 2014-05-05 21:45:26

Voici l'exemple sur ce qui a fonctionné pour moi. Je pense que la méthode put est nécessaire dans la classe entity pour mapper les colonnes sql aux attributs de classe java.

    //simpleExample
    Query query = em.createNativeQuery(
"SELECT u.name,s.something FROM user u,  someTable s WHERE s.user_id = u.id", 
NameSomething.class);
    List list = (List<NameSomething.class>) query.getResultList();

classe d'Entité:

    @Entity
    public class NameSomething {

        @Id
        private String name;

        private String something;

        // getters/setters



        /**
         * Generic put method to map JPA native Query to this object.
         *
         * @param column
         * @param value
         */
        public void put(Object column, Object value) {
            if (((String) column).equals("name")) {
                setName(String) value);
            } else if (((String) column).equals("something")) {
                setSomething((String) value);
            }
        }
    }
0
répondu aborskiy 2017-01-24 17:28:34