Avatar billede kernelx Juniormester
30. januar 2013 - 18:35 Der er 3 kommentarer og
1 løsning

JPA2 GROUP BY med CriteriaBuilder.concat

Hi,

Jeg har en oracle db og følgende JPA2 kode:
===========================
EntityManagerFactory emf = Persistence.createEntityManagerFactory("Test");
EntityManager em = emf.createEntityManager();
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<Tuple> query = cb.createTupleQuery();
Root<?> testEntity = query.from(IconEntity.class);
Expression<?> expression = cb.concat(
        testEntity.get("id").as(String.class),
        "_"  // den virker ikke
);
query.multiselect(expression.alias("foo"));
query.groupBy(expression);
TypedQuery<Tuple> typedQuery = em.createQuery(query);
List<Tuple> resultList = typedQuery.getResultList();
===========================

typedQuery.getResultList() kaster en exception med
Missing IN- or OUT-Parameter for Index:: 2 {prepstmnt 1262795103 SELECT (t0.ID||?) AS foo FROM TBL_TEST t0 GROUP BY (t0.ID||?) [params=?]} [code=17041, state=99999]

Koden virker hvis jeg enten fjerner "query.groupBy(expression);" eller hvis jeg ikke direkte insætter en String som anden parameter i cb.concat() og laver en concat uden String.
----
Expression<?> expression = cb.concat(
        testEntity.get("id").as(String.class),
        testEntity.get("id").as(String.class)
);
---

Hvis jeg laver
SELECT (t0.ID||'_') AS foo FROM TBL_TEST t0 GROUP BY (t0.ID||'_')
direkte i oracle, så virker det også.

Så mit spørgsmål er:
Hvordan kan jeg få min criteria query til at have en String parameter uden at openJPA laver en parameter i min query >>?<< og i stedet for direkte insætter min String >>'_'<<?

Mange tak for hjælp!
Avatar billede kernelx Juniormester
02. februar 2013 - 14:19 #1
Jeg har fundet en workaround, i det jeg laver concat og group by i en subquery. Med subquery virker det.

Jeg venter lidt for svar. Måske er der nogen, som har en bedre løsning og er glad for 200 points.

Hvis ikke, så lukker jeg svaret, om ca en uge.

Med venlig hilsen
KernelX
Avatar billede arne_v Ekspert
03. februar 2013 - 03:50 #2
1) Det ligner en bug - har du set om der er en nyere version af din JPA provider?

2) Hvad med at erstatte den underscore med en parameter?

3) Jeg forstaar ikke logikken. Hvorfor ikke undlade at konkatanere og saa tilfoeje den underscore i Java?
Avatar billede kernelx Juniormester
04. februar 2013 - 20:15 #3
1.) Jeg har ingen muligheder for at ændre min JPA provider. Den sidder fast i en JEE6-Container (Websphere). Så hvis det er en bug, så melder jeg det.

2.) Har jeg prøvet. Så kom den med en anden exception. Det ser ud til at den på en eller anden måde ikke kan lide denne kombination med GROUP BY.

3.) Det er meget svært at forklare. Det hat noget at gøre med meget komplexe queries, som har nogen LEFT OUTER JOINS. Nogle af de JOINede entitier skal grouperes - andre ikke. Dem som ikke skal grouperes bliver alligevel brugt, som "filter". De IDer som skal grouperes, skal grouperes i en subquery (heldigvis - Jeg skulle have testet det i en subquery med det samme).
I en subquery er det ikke så nemt at groupere på flere columns i JPA (med andre ord: jeg var for dum til at finde ud af hvordan uden multiselect).
Så jeg tænkte mig at Concatinere alle IDer i en column, sådan, at JPA ikke har problemer med det, i denne kontext, som jeg har brug for det.
Nu, hvor ID-værdierne er concatineret i en column og en group by er udført på dem, har jeg et antal af rows, som kommer ud af det.
Og det er antallet af disse rows, som jeg skal have fat i.
Så i endet bliver der lavet en countDistinct på mit subquery ... og voila, jeg har min total-value :-)

Sorry mit dansk er ikke det bedste. Håber at jeg nogenlunde kunne forklare mit problem, som jeg nu fik løst.

Mange tak for hjælp. Husk at skrive et eller andet som svar.
Avatar billede arne_v Ekspert
06. februar 2013 - 03:48 #4
Det lyder som en query der vil traekke taender ud.

Jeg kan godt smide et svar, men jeg ved ikke helt om jeg har hjulpet.
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester