# JPQL - Join Verkettung



## Mr_Burns (25. Okt 2011)

Hallo Zusammen!

Ich bin noch ziemlich neu was JPQL angeht. Wahrscheinlich ist es ein trivialer Fehler. Aber ich finde keine Lösung. Würde mich freuen wenn mir jemand weiterhelfen kann.

Ich habe folgende Abfrage erstellt. Diese liefert aber leider keine Ergebnisse. Warum?

```
SELECT DISTINCT e FROM Customer AS e
JOIN e.personOfContacts e_personOfContacts
JOIN e_personOfContacts.posContacts posContacts
WHERE (e.customerName LIKE :term OR posContacts.contactValue LIKE : term)
```

Lasse ich die OR Bedingung weg und frage nur nach contactValue erhalte ich Ergebniss

```
SELECT DISTINCT e FROM Customer AS e
JOIN e.personOfContacts e_personOfContacts
JOIN e_personOfContacts.posContacts posContacts
WHERE posContacts.contactValue LIKE : term
```

Lasse ich die OR Bedingung weg und frage wiederum nur der customerName ist die Ergebnisliste wieder leer:

```
SELECT DISTINCT e FROM Customer AS e
JOIN e.personOfContacts e_personOfContacts
JOIN e_personOfContacts.posContacts posContacts
WHERE customerName LIKE : term
```

Meine Entities:

```
@MappedSupperclass
public abstract class AbstractBaseEntity implements Serializable {

    @Id
    String uuid;
    
    ....
}

@Entity
public class Customer extends AbstractBaseEntity {

    String customerName;

    @OneToMany(mappedBy="customer", cascade=CascadeType.ALL, orphanRemoval=true)
    private List<PersonOfContact> personOfContacts;

    ....
}

@Entity
public class PersonOfContact extends AbstractBaseEntity {

    @OneToMany(mappedBy="personOfContact", cascade=CascadeType.ALL, orphanRemoval=true)
    private List<PosContact> posContacts;

    ....
}

@Entity
public class PosContact extends AbstractBaseEntity {

    String contactValue;

    ....
}
```

Bin für jeden Hinweis dankbar.
Grüsse


----------



## maki (25. Okt 2011)

Du willst bestimmt kein LIKE auf eine ID.
Die sollte doch entweder exakt stimmen, oder nicht


----------



## Mr_Burns (25. Okt 2011)

maki hat gesagt.:


> Du willst bestimmt kein LIKE auf eine ID.
> Die sollte doch entweder exakt stimmen, oder nicht



@maki
Stimmt, das LIKE auf der customerId ist natürlich quatsch. Ich habe beim kürzen des Quelltexts und posten die erste Eigenschaft der Klasse Customer genommen ohne darauf zu achten. Habe meine Anfrage entsprechend geändert (von customerId nach customerName).

Siehst Du evtl. den Fehler in der Abfrage?

Grüsse


----------



## SlaterB (25. Okt 2011)

einen Fehler könnte man in begrenzter Informationsbeschaffung sehen,
wie läuft denn mit einer normale Query ohne Joins

```
SELECT DISTINCT e FROM Customer AS e
WHERE customerName LIKE : term
```
?

wie sieht es ohne Like aus, mit normalen =, gehen mehrere normale =-Bedingungen mit OR verknüpft?,
macht LIKE bei anderen Feldern Probleme? oder klappt dort alles, auch OR?
welche Werte sind beteiligt, hat es was mit null zu tun, 
kommt ganz ohne WHERE-Einschränkung genügend heraus?


----------



## maki (25. Okt 2011)

Ich hätte gesagt, das LIKE auf eine ID schon falsch ist, da wird zB. mit id LIKE %12_ nicht viel gefunden werden können...


----------



## Mr_Burns (25. Okt 2011)

@SlaterB
@maki
Zunächst möchte ich einmal Danke sagen für die schnellen Antworten.

Normale Abfrage ohne Join geht:

```
SELECT DISTINCT e FROM Customer AS e
WHERE e.customerName LIKE :term
```

Auch mehrere OR bringt die zu erwartenden Ergebnisse:

```
SELECT DISTINCT e FROM Customer AS e
WHERE e.customerName LIKE :term OR e.customerNick LIKE :term OR e.customerAlias LIKE :term";
```

Allerdings könnte NULL ein Hinweis sein. Ich prüfe das gerade. Kann aber etwas dauern, da ich wie gesagt neu in der Materie bin.


----------



## Mr_Burns (25. Okt 2011)

Folgendes konnte ich bis jetzt herausfinden:

Angenommen ich habe zwei Kunden:

Maier (mit contactValue Eintrag)
Maler (ohne contactValue Eintrag)

Wenn ich jetzt nach 
	
	
	
	





```
Ma
```
 suchen lasse spuckt er mir NUR *Maier* aus. Ich würde aber gerne haben, dass er Maier + Maler ausgibt (also alle Einträge die Ma enthalten egal ob ein contactValue Eintrag vorhanden oder nicht). Nur wie mache ich das???


----------



## Mr_Burns (25. Okt 2011)

Lösung:

```
SELECT DISTINCT e FROM Customer AS e
JOIN e.personOfContacts e_personOfContacts
LEFT JOIN e_personOfContacts.posContacts posContacts
WHERE (e.customerName LIKE :term OR posContacts.contactValue LIKE : term)
```

Man beachte das 
	
	
	
	





```
LEFT
```
. Auf diese Weise werden Maier und Maler (aus obigem Beispiel) ausgeworfen.

Nochmals Danke an SlaterB und maki. Konstruktive Hilfe. Tolles Forum das Ihr hier betreibt.


----------



## SlaterB (25. Okt 2011)

LEFT JOIN - SQL
ist grundsätzlich das Mittel dazu,
im Detail für mich aber immer wieder kompliziert, hast du da eigentlich SQL oder eine andere Abfragesprache (in Hibernate gibts HQL)?

ich glaube du musst auf (x is null or x like ..) abfragen, neben der grundsätzlich richtig eingebauten Left Join-Verknüpfung natürlich,
am besten erstmal ohne WHERE auf übersichtlichen Dummy-Tabellen/ Entities üben

edit: na das ging dann ja leicht, umso besser


----------

