# Hibernate - spezielle Frage, n zu n Beziehung



## sina.die (24. Nov 2009)

Hallo,

ich bin recht neu bei der Datenbankprogrammierung und Hibernate und versuche ein für mich schwieriges Problem zu lösen.

In meinem Datenmodell(richtiger Begriff? Ich meine die Java-Seite) habe ich eine n-n-Beziehung. In der Realität ist es jedoch so, dass hier eine 1-1 Beziehung besteht. In Zukunft soll das wohl an dem Modell geändert werden. Momentan steht das jedoch nicht in meiner Macht dies zu tun.

Nun möchte ich ein Objekt, von dem ich weiß, dass es sich als einziges in der Liste befindet, auf etwas prüfen, weiß aber nicht, wie ich das realisiere, da sich diese eine zusätzliche Abfrage in einer sehr langen DB-Anfrage befindet.
Eigentlich würde ich gern sowas machen, wie: 

```
...
sqlSelect.append(" and objekt1.getObjekts2().iterator().next().getId() IN (ein Subselect, der Ids von verschiedenen Objekt2 liefert)");
...
```
Mir ist klar, dass das Blödsinn ist, aber wie kann ich da denn sonst drankommen? Für den Subselect brauche ich keine Hilfe. Nur für den ersten Teil.

Danke im vorraus,
Sina


----------



## maki (24. Nov 2009)

> In meinem Datenmodell(richtiger Begriff? Ich meine die Java-Seite)


Je nachdem, "Datenmodell" beschreibt eigentlich nur die Relationen zwischen Daten, kein Verhalten.
Wenn deine Klassen "dumme" JavaBeans sind ohne Logik und nur mit Gettern & Settern, dann passt Datenmodell.
Wenn auch verhalten (also Logik) in den Klassen steckt, wäre es wohl ein Domänenmodell.
Im Allgemeinen wird aber nicht so genau unterschieden...



> habe ich eine n-n-Beziehung. In der Realität ist es jedoch so, dass hier eine 1-1 Beziehung besteht. In Zukunft soll das wohl an dem Modell geändert werden. Momentan steht das jedoch nicht in meiner Macht dies zu tun.


Persönlich würde ich dann eine 1:1 Beziehung machen, ist viel einfacher, und wer weiss ob die Änderung wirklich noch kommt... und wenn sie kommt, ob nicht noch mehr Änderungen kommen und was dann alles geändert werden muss.
Es ist tatsächlich so, dass Dinge sich am einfachsten ändern lassen, wenn sie einfach sind 



> Nun möchte ich ein Objekt, von dem ich weiß, dass es sich als einziges in der Liste befindet, auf etwas prüfen, weiß aber nicht, wie ich das realisiere,


Hibernate bietet neben der HQL auch noch die Criteria API, solltest dir beides mal ansehen


----------



## sina.die (24. Nov 2009)

maki hat gesagt.:


> Persönlich würde ich dann eine 1:1 Beziehung machen, ist viel einfacher, und wer weiss ob die Änderung wirklich noch kommt... und wenn sie kommt, ob nicht noch mehr Änderungen kommen und was dann alles geändert werden muss.
> Es ist tatsächlich so, dass Dinge sich am einfachsten ändern lassen, wenn sie einfach sind


Ich habe leider keine Berechtigung dies in dem Datenmodell zu tun :-(
Und die Mühlen nach oben hin mahlen langsam...



maki hat gesagt.:


> Hibernate bietet neben der HQL auch noch die Criteria API, solltest dir beides mal ansehen


Danke, gesehen hab ich das auch schon. Wühle mich noch durch den Code von Vorgängern... Es waren wohl mehrere am Werk und die Anfragen wurden unterschiedlich implementiert. Aber wie ich das Problem damit löse, weiß ich auch nicht.


----------



## gman (24. Nov 2009)

Hi,

ich bin mir nicht sicher ob ich deine Frage jetzt richtig verstanden habe. Aber wenn du das "objekt1" hast, dann mach doch einfach das was du als Beispiel geschrieben hast:


```
sqlSelect.append(" and ");
sqlSelect.append(objekt1.getObjekts2().iterator().next().getId());
sqlSelect.append(" IN (Subselect)");
```

Oder musst du mit der Abfrage erstmal beide Objekte ermitteln?

Gruß


----------



## sina.die (25. Nov 2009)

gman hat gesagt.:


> Oder musst du mit der Abfrage erstmal beide Objekte ermitteln?


Ja, ich habe objekt1 an der Stelle noch nicht. Ich versuche, dass mal irgendwie umzubiegen, bin aber weiterhin für andere Vorschläge dankbar.

Edit:
Und das Problem ist auch, dass ich in der Anfrage auch mehrere objekt1 erwarte, die als Bedingung haben, dass sie ein objekt2 in einer Liste besitzen, welches eine Id hat aus der Liste mit Ids aus dem Subselect.

Ich meine, irgendwie komme ich an die Daten. Meine Notlösung war nun erstmal die Ids vom Typ Objekt2 in einer Liste zu holen und im Javacode habe ich es dann durch for-Schleifen laufen lassen, um an die richtigen Objekte vom Typ 1 zu kommen, aber es kommt mir halt falsch vor in einer DB-Anfrage mehr Daten zu holen, als ich eigentlich brauche.


----------



## byte (25. Nov 2009)

Mit HQL kannst Du das in etwa so erreichen (
	
	
	
	





```
objekts
```
ist der Name des Members in Klasse 
	
	
	
	





```
Foobar
```
):


```
from Foobar foo where foo.objekts[0].id in ( SUBSELECT )
```


----------



## sina.die (25. Nov 2009)

Danke, das wäre perfekt.
Ich habe es gerade ausprobiert und bekomme sowas: org.hibernate.QueryException: unindexed fromElement before []

Ich nehme an, es liegt daran, dass da HashSets benutzt werden. Die eigentliche Auflösung zu dem Objekt, welches ich bräuchte, sähe etwa so aus: foo.objekts.set.map.table[?]


----------



## byte (25. Nov 2009)

Das funktioniert nur bei indexed collections, also nicht bei Sets. Da fällt mir aber ein, Du kannst doch auch einfach sowas machen, wenns objekts sowieso nur 1 Element enthält:


```
FROM Foobar foo WHERE foo.objekts.id IN ( SUBSELECT )
```


----------



## sina.die (25. Nov 2009)

Hmm, da bekomme ich dann sowas:

org.hibernate.QueryException: illegal attempt to dereference collection [objekt10_.OBJEKT1_ID.objects2] with element property reference [objekt2Id]

(Habe die Namen manuell in Objekt1 und Objekt2 geändert, eigentlich heißen sie anders - nur falls ich mich irgendwo vertippt habe und irgendwas unlogisch ist...)


----------



## byte (25. Nov 2009)

Hm, sagt mir gar nix. Vielleicht mal explizit joinen?


```
FROM Foobar foo left join foo.objekts o WHERE o.id IN ( SUBSELECT )
```

Was generiert er denn für ein SQL und wie sieht das Mapping aus?


----------



## sina.die (25. Nov 2009)

byte hat gesagt.:


> Hm, sagt mir gar nix. Vielleicht mal explizit joinen?
> 
> ```
> FROM Foobar foo left join foo.objekts o WHERE o.id IN ( SUBSELECT )
> ```



Das war es! Vielen, vielen Dank!


----------



## byte (25. Nov 2009)

Freut mich dass es so geklappt hat.


----------

