2013-03-14 19 views
7

È possibile scrivere questa query come TypedQuery e lasciare che i due Long vengano eseguiti in un oggetto con all'interno due campi Long pubblici.TypedQuery anziché normale Query in JPA

Query q = em.createQuery(
      "SELECT c.id, COUNT(t.id) " + 
      "FROM PubText t " + 
      "JOIN t.comm c " + 
      "WHERE c.element = ?1 " + 
      "GROUP BY c.id"); 
    q.setParameter(1, e); 
    List<?> rl = q.getResultList(); 
    Iterator<?> it = rl.iterator(); 
    HashMap<Long, Long> res = new HashMap<Long, Long>(); 
    while (it.hasNext()) { 
     Object[] n = (Object[]) it.next(); 
     res.put((Long)n[0], (Long)n[1]); 
    } 
    return res; 

risposta

12

APP ha una funzione solo per questo - espressioni costruttore:

Query q = entityManager.createQuery("SELECT NEW com.example.DTO(c.id, COUNT(t.id)) FROM ..."); 
List<DTO> dtos = q.getResultList(); 

La classe DTO può essere un POJO. Tutto ciò di cui ha bisogno è un costruttore pubblico che accetta 2 Long s. Si prega di notare che è necessario fornire un nome completo della classe dopo l'operatore NEW.

+0

hi @kostja Mi viene visualizzato un errore (Impossibile creare TypedQuery per la query con più di un ritorno). Il mio SQL ha questo aspetto: 'SELEZIONA NUOVO com.company.ui.EntityIDKey (c.companyId, c.name) FROM Azienda c WHERE c.companyId non è nullo e c.name non è nullo e lunghezza (trim (c.name))> 0 ordina per c.name asc'. Sto usando un TypedQuery come segue: 'Elenco companies = getEntityManager(). CreateQuery (sql, EntityIDKey.class) .getResultList();' –

+1

questo può essere il caso se il tuo EntityIDKey non è un'entità. Il provider è libero di non supportare tali query. Hai provato a usare una normale Query? – kostja

+0

è vero, "EntityIDKey' non è un'entità. Sto usando il fornitore di Hibernate e presumibilmente in qualche modo funzionerà. Una query regolare che crea una raccolta di 'Company' funziona perfettamente. –

8

Il nuovo codice appare ora. Grazie per il tuo aiuto.

TypedQuery<CommUsed> q = em.createQuery(
     "SELECT new CommUsed(c.id,COUNT(t.id)) " + 
     "FROM PubText t " + 
     "JOIN t.comm c " + 
     "WHERE c.element = ?1 " + 
     "GROUP BY c.id", CommUsed.class); 
    q.setParameter(1, e); 
    HashMap<Long, Long> res = new HashMap<Long, Long>(); 
    for (CommUsed u : q.getResultList()) 
     res.put(u.commID, u.cnt); 
+0

Vedo, quindi è possibile utilizzare TypedQueries dopo tutto :) Buono a sapersi. Sfortunatamente non sembra esserci un modo ragionevole per riempire una 'Mappa 'direttamente dalla query, quindi la parte di trasformazione nelle ultime 3 righe deve rimanere, temo. – kostja

+1

Ach, quella fine. Non abbiamo bisogno di premere tutto in una riga come nei vecchi C giorni. :-) –

+0

@HasanTuncay perché non hai sfruttato la funzione di espressione del costruttore suggerita da @kostja? –