# JPA Liste mit mehreren Entitäten



## internet (3. Mai 2014)

Hallo zusammen,

für eine "Geburtstagsuche" möchte ich gerne eine List ausgeben, die mir die Geburtstage von Mitarbeiter und Kunden ausgibt.

Also vereinfacht erst mal alle Kunden und alle Mitarbeiter.


```
SELECT e,c FROM Employee e, Customer c
```

Nun ist mein Problem in welchem Datentyp ich das Ganze in einer Liste speichere.
Mein Ansatz ist nun das ganze in eine *List<Object> list* zu speichern.

Das Problem ist nun jedoch, dass ich dann ja bspw. im Feld[0] des Arrays sowohl der Customer, als der Employee gespeichert bekomme. Allerdings sollen es ja zwei Felder sein.

Generel ist es natürlich möglich eine Liste vom Typ Date List<Date> zu erstellen, macht für mich aber kein Sinn, da ich später zudem auch einen Link auf den Employee und Customer in der HTML-Seite hinzufügen möchte-> geht also nicht.

Gibt es hierbei irgendwelche Lösungsansätze?


Mein derzeitger Lösungsansatz ist:
Zwei Query mache:
 1.) Eine Query, das mir die Geb. der Customer liefert
 2.) Eine Query, das mir die Geb. der Employee liefert.

Beide Ergebnismengen "verheirate" ich wiederum in eine dritte Liste, welche von einem Typ "CustomClass" ist. CustomClass hat zwei Attribute
a) Customer b) Employee
=> Die Customer aus der ersten Query befülle ich dann eben in die dritte Liste mit dem Attribut Customer, und das gleiche für die Employees.

Okay, funktioniert auch - aber ich denke professionell und schön ist das nicht???
WARUM?
Beispiel: Ich möchte mir die *nächsten* 100 Geburtstage von Employee und Customer ansehen.
Insgesamt sind über 100 Employees und über 100 Customer in der DB .
Zunächst holt er alle 100 Geb der Customer. Dann die 100 Geb. der Employee => Macht also schon Mal 200 Geburtstag (ich möchte aber nur 100 anzeigen!!!)

Nun muss ich nochmals eine Sortierung vornehmen, die dann wirklich nur die kommenden Geb. in die dritte Liste speichert.
Ich denke das könnte ein "Performance-Killer" werden.

Kann mir hierfür bitte jemand Tipps geben, wie ich das anderst lösen kann?

Vielen Dank für Eure Hilfen...


----------



## turtle (3. Mai 2014)

Ich habs nicht ganz verstanden

Stehen Employee  und Customer in einer Beziehung?

Dann kann man einen Join nutzen und Einträge aus beiden (oder mehreren) Tabellen referenzieren und muss die Beziehungen angeben.

Nehmen wir an, das jeder Employee "seinen" bestimmten Customer gehört.

Dann sollte es so gehen:

SELECT e,c  FROM Employee e, Customer c WHERE e.customerid=c.id and e.birthdate BETWEEN :date1 AND :date2


----------



## internet (4. Mai 2014)

Danke für Deine Antwort.

Employee und Customer stehen in einer Beziehung.
Dies geschieht über die Entität "Mandanten". Ich wollte diese Entität bei der Frage aber bewusst weglassen, da es vermutlich verwirrt hätte.

Das eigentliche Problem ist ja, dass ich zwei unterschiedlich Entitäten bei Deiner Query bekomme (Employee und Customer). 


> Also bei SELECT e,c



Nun möchte ich ja aber eine Liste, in der die Ergebnisse (also entweder Employee ODER Customer) gespeichert werden.
Mein Problem ist jetzt aber: Welchen *Datentyp* muss diese Liste haben?


```
List<????> meineListe = new ArrayList<????>();
```


----------



## Deros (5. Mai 2014)

spontan würde ich wohl sowas machen:

select 'Employee' Typ, e.id Id, e.birthdate gebDatum from Employee e
union
select 'Customer ' Typ, c.id Id, c.birthdate gebDatum from Customer c
where
e.birthdate BETWEEN :date1 AND :date2
and
c.birthdate BETWEEN :date1 AND :date2


----------



## internet (5. Mai 2014)

und von welchem Datentyp soll das sein?


```
List<????> meineListe = new ArrayList<????>();
```


----------



## Deros (5. Mai 2014)

sowas müsste schon funktionieren



```
TypedQuery<Object[]> query = em.createQuery(
"select 'Employee' Typ, e.id Id, e.birthdate gebDatum from Employee e
union
select 'Customer ' Typ, c.id Id, c.birthdate gebDatum from Customer c
where
e.birthdate BETWEEN :date1 AND :date2
and
c.birthdate BETWEEN :date1 AND :date2 ", Object[].class);
 List<Object[]> results = query.getResultList();
```


----------



## internet (5. Mai 2014)

habs gerade getestet, leider funktioniert die Query nicht:bahnhof:


----------



## Deros (6. Mai 2014)

und eine Fehlermeldung willst uns nicht verraten?
so wie die Querry da steht funktioniert sie natürlich nicht, der String muss natürlich konkateniert werden und date1 und date2 jeweils befüllt.


----------



## internet (7. Mai 2014)

Fehlermeldung ist, dass das SQL-Statement nicht richtig ist bzw. ein Fehler drin ist.
Ich habe es mal nun versucht ohne Date - Bedingung, da ich das mit "Typ" noch nie gemacht habe.
Hier meine Query:



> "select 'Employee' Typ, e from Employee e union select 'Customer ' Typ, c from Customer c",



Kannst Du mir sagen, was ich falsch mache bzw. wie die Query richtig heißen müsste?


----------



## Deros (8. Mai 2014)

du musst die einzelnen Spalten angeben also was in der richtung:


```
"select 'Employee' Typ, e.geburtstag, e.name from Employee e union select 'Customer ' Typ, c.geburtstag, c.name from Customer c",
```


----------



## internet (8. Mai 2014)

ich möchte aber den ganzen Employee ausgeben - also quasi alle Felder, die ein Employee und Customer hat...

Wie mache ich das?


----------



## Deros (8. Mai 2014)

gibst halt alle Felder an


----------



## internet (8. Mai 2014)

geht das nicht auch wie "sonst" einfach mit Employee e ?


----------



## Deros (8. Mai 2014)

hast doch festgestellt das ne Fehlermeldung kommt also was willst du jetzt von mir hören?
Ist jetzt doch kein akt die spaltennamen anzugeben oder?


----------



## internet (8. Mai 2014)

naja, wenn du einen Kunden hast, der etliche Informationen hat (sagen wir mal 20 Attribute) ist das schon nervig, die alle mit anzugeben...


----------



## internet (8. Mai 2014)

folgende Fehlermeldung bekomme ich:



> unexpected token: Typ: line 1:19: unexpected token: Typ


----------



## Deros (9. Mai 2014)

ich denke es geht um eine Geburtstagssuche? wofür brauchst du da weitere 20 Spalten?

wenn man dir irgendwie mit der Fehlermeldung helfen können soll, musst du schon die gesamte Fehlermeldung posten und den Code dazu am Besten auch.


----------



## internet (9. Mai 2014)

Der Fehler tritt bei folgender Query auf:


```
select 'Employee' Typ, e.geburtstag, e.name from Employee e union select 'Customer ' Typ, c.geburtstag, c.name from Customer c
```

Irgendwas stimmt wohl mit dem "Typ" nicht zu stimmen.
Lassen wir das mit dem Geburtstag mal ausen vor:

Ich möchte im Grunde genommen alle Employee und Customer ausgeben, die zu einem Mandatory gehören:
Im Prinzip baue ich mir zwei Querys:



> select e from Employee e where e.mandatory.id = 1





> select c from Customer c where c.mandatory.id = 1



Das funktioniert ja nun auch alles wunderbar. Nun möchte ich aber die Ergebnisse dieser zwei Listen in EINE Liste zusammenfassen.
Ich habe das über einen UNION funktioniert - dann bekomme ich aber nur einen Eintrag mit dem Employee und dem Customer.
Ich möchte aber wenn ich 1 Customer und 1 Employee habe, auch zwei Einträge herausbekommen.

Wie mache ich das am Besten?


----------



## Deros (10. Mai 2014)

Was für eine DB nutzt du denn?


```
select 'Employee' as Typ, e.geburtstag, e.name from Employee e union select 'Customer ' as Typ, c.geburtstag, c.name from Customer c
```

kannste mal probieren, ansonsten kannst die Spalte auch weglassen, sollte nur zum unterscheiden von customer und employee sein. Ansonsten wäre die komplette Fehlermeldung noch immer wünschenswert


----------



## internet (11. Mai 2014)

so, die Query geht nun OHNE Fehler.
Allerdings bekomme ich immer nur den Employee heraus. Also sprich der *UNION* funktioniert nicht?

Was muss ich hierzu noch machen?


----------



## Deros (12. Mai 2014)

Junge ich gebe es auf...Der UNION funktioniert mit Sicherheit, wenn du ihn richtig nutzt, aber man muss dir ja ständig aus der Nase ziehen, was du gerade machst. Wie sieht das Statement aus? Was für einer DB nutzt du? Wie sieht dein restlicher Code aus? mal das Statement direkt auf die DB losgelassen ausserhalb von JAVA? ;(


----------



## internet (18. Mai 2014)

Die Query sieht so aus:


```
SELECT 'Employee' AS Typ, e.geburtstag, e.name FROM Employee e UNION SELECT 'Customer ' AS Typ, c.geburtstag, c.name FROM Customer c
```

- Als DB nutze ich MySQL
- Das Ganze eben mit JPA / Hibernate

Restlicher Code habe ich nicht - ich möchte erst mal die Query zum Laufen bekommen...


----------



## Deros (18. Mai 2014)

Hast du die Querry im MySQL-Workbench laufen lassen? wenn nein gibt es mit Sicherheit mehr Code, vielleicht läufst ja einfach falsch durch die Liste, so ist alles blödes raten und da habe ich echt keinen bock drauf...


----------

