2013-03-14 9 views
7

Ist es möglich, diese Abfrage als TypedQuery zu schreiben und die beiden Long Run in ein Objekt mit zwei öffentlichen Langen Feldern innerhalb lassen.TypedQuery anstelle der normale Abfrage 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; 

Antwort

12

JPA verfügt über eine Funktion nur für diesen - Konstruktor Ausdrücke:

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

Ihre DTO-Klasse ein POJO sein kann. Alles, was es brauchen wird, ist ein öffentlicher Konstruktor, der 2 Long s akzeptiert. Bitte beachten Sie, dass Sie nach dem Operator NEW einen vollständig qualifizierten Namen Ihrer Klasse angeben müssen.

+0

hi @kostja Ich erhalte einen Fehler (kann TypedQuery für Abfrage mit mehr als einer Rückkehr nicht erstellen). Mein SQL sieht so aus: 'SELECT NEW com.company.ui.EntityIDKey (c.companyId, c.name) FROM Firma c WHERE c.companyId ist nicht null und c.name ist nicht null und länge (trim (c.name))> 0 order by c.name asc'. Ich verwende einen TypedQuery wie folgt:. 'Liste Unternehmen = getEntityManager() Create (SQL, EntityIDKey.class) .getResultList();' –

+1

kann dies der Fall sein, wenn Ihr EntityIDKey keine Einheit ist. Der Anbieter kann solche Anfragen nicht unterstützen. Haben Sie versucht, eine normale Abfrage zu verwenden? – kostja

+0

das ist wahr, "EntityIDKey" ist keine Entität. Ich verwende den Hibernate-Provider und vermutete irgendwie, dass es funktioniert. Eine reguläre Abfrage, die eine Sammlung von "Firma" erstellt, funktioniert gut. –

8

New Code sieht nun wie folgt aus. Danke für Ihre Hilfe.

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

Ich sehe, so können Sie TypedQueries nach allem :) gut zu wissen. Leider scheint es keinen vernünftigen Weg zu geben, eine 'Map' direkt aus der Anfrage zu füllen, also muss der Transformationsteil in den letzten 3 Zeilen bleiben, fürchte ich. – kostja

+1

Ach, das ist in Ordnung. Wir müssen nicht alles wie in den alten C-Tagen in eine Linie drücken. :-) –

+0

@HasanTuncay Warum haben Sie die Konstruktorausdruckfunktion, die von @kostja vorgeschlagen wird, nicht genutzt? –