[Eclipselink] Wie verhält sich "groupBy() im CriteriaQuery?

Hallo Forum,

ich habe gerade ein (hoffentlich) simples Verständnisproblem mit GroupBy im CriteriaQuery.

CriteriaQuery<AdrInfo> cq = cb.createQuery(AdrInfo.class);
Root<AdrInfo> adrInfo = cq.from(AdrInfo.class);  
        
Predicate artNrNotNull = cb.isNotNull(adrInfo.get(AdrInfo_.deklaration));        
Predicate artNrNotEmpty = cb.notEqual(adrInfo.get(AdrInfo_.deklaration), "");
Predicate deutsch = cb.equal(adrInfo.get(AdrInfo_.sprache), "d");
Predicate and = cb.and(artNrNotNull, artNrNotEmpty, deutsch);
        
cq.select(adrInfo).groupBy(adrInfo.get(AdrInfo_.deklaration)).where(and);
        
List<AdrInfo> result = getEntityManager().createQuery(cq).setMaxResults(pageSize).setFirstResult(first).getResultList();```

Kurzer Hintergrund: Der Anwender bekommt eine Liste von Gefahrgutangaben verschiedener Produkte in unserer DB und kann einen davon auswählen. Ich möchte aber, dass doppelte Deklarationen nicht angezeigt werden und möchte das Result nach dem Feld "Deklaration" gruppieren.

So sieht das ganze in der Spezi von Oracle aus:
```CriteriaQuery<Pet> cq = cb.createQuery(Pet.class);
Root<Pet> pet = cq.from(Pet.class);
cq.groupBy(pet.get(Pet_.color));
//This query returns all Pet entities and groups the results by the pet’s color.```

Ich fühle mich also schon mal auf dem richtigen Weg, aber WIE werden die Ergebnisse gruppiert? Im "Plain Old SQL" muss ich auf Felder, welche nicht in der Group Bedingung genannt sein ja eine Aggregatfunktion anwenden, das passiert hier gar nicht? Ich habe aber noch keine Spezifikation hierzu gefunden, wie sich das verhält. Weiß jemand von euch da mehr?

Gruß,
Tim

Hi,

habe es mittlerweile herausgefunden. Gruppierte Objekte zu selektieren ist ziemlich dreckig, da die Ergebniss zum einen “seltsam” sein können und außerdem hierdurch die im Speicher vorhandenen Entities kompromittiert werden können, was bei genauem Nachdenken eigentlich auch nur logisch ist. Ich selektiere jetzt mit “multiselect” auf min(id) und die Deklaration, das reicht für meine Zwecke aus.


CriteriaQuery cq = cb.createQuery();
Root<AdrInfo> adrInfo = cq.from(AdrInfo.class);

Predicate artNrNotNull = cb.isNotNull(adrInfo.get(AdrInfo_.deklaration));
Predicate artNrNotEmpty = cb.notEqual(adrInfo.get(AdrInfo_.deklaration), "");
Predicate deutsch = cb.equal(adrInfo.get(AdrInfo_.sprache), "d");
Predicate and = cb.and(artNrNotNull, artNrNotEmpty, deutsch);

cq.multiselect(cb.min(adrInfo.get(AdrInfo_.id)), adrInfo.get(AdrInfo_.deklaration));
cq.groupBy(adrInfo.get(AdrInfo_.deklaration));
cq.where(and);

List<Object[]> result = getEntityManager().createQuery(cq).setMaxResults(pageSize).setFirstResult(first).getResultList();

Gruß,
Tim