# Hibernate Realationen



## OnDemand (15. Aug 2020)

Hallo zusammen,

ich bin grad dabei meine Entitäten etwas zu überarbeiten und stelle mir die Frage, wann ist es sinnvoll/korrekt ein Objekt als Relation an eine Entität zu hängen wenn ich doch nur die IDs brauche. Hoffe es ist irgendwie zu verstehen worauf ich hinaus will.

Beispiel eine "Bestellung" hat folgende Felder:
- int orderNumber
- ...
- List<Product> products
-...

Wenn ich nun eine Bestellung lade, brauch ich nur die ID der Produkte. Es wäre unnötig das Produkt komplett zu laden. Wenn ich mehr zum Produkt brauch, kann ich mir das Produkt anhand der ID holen. 

Wie wäre es sinnvoll? LazyLoading? Die Bestellung gleich von Anfang an nur mit_ List<Integer> ID_ zu speichern oder ein ganz anderer Ansatz?


----------



## mihe7 (15. Aug 2020)

Bei der Überlegung helfen die Aggregates aus dem Domain Driven Design. Die Klasse Bestellung dürfte die Wurzel eines Aggregats sein, die Klasse Product dagegen ist *nicht* Bestandteil dieses Aggregats (sondern dürfte die Wurzel eines eigenen Aggregats darstellen). Daher werden keine Objektreferenzen, sondern ProductIDs verwendet. Wenn Du diese nicht explizit modellierst, kannst Du auch den Typ der ID verwenden.


----------



## thecain (15. Aug 2020)

Hibernate bietet dafür den FetchType LAZY, den man zu 99% sowieso verwenden sollte. Dann kann man die Entitäten korrekt modellieren und lädt trotzdem nicht die halbe Datenbank.


----------



## mihe7 (15. Aug 2020)

thecain hat gesagt.:


> Hibernate bietet dafür den FetchType LAZY, den man zu 99% sowieso verwenden sollte.


Wobei das nicht spezifisch für Hibernate gilt. Die Objektreferenzen verwenden wir nur innerhalb eines Aggregats (=transaktionale Einheit), über Aggregatgrenzen hinweg wird dagegen die ID verwendet.


----------



## thecain (15. Aug 2020)

Meinem Verständnis nach wäre Referenz ok.


> Objects within the AGGREGATE can hold references to other AGGREGATE roots.


----------



## mihe7 (16. Aug 2020)

thecain hat gesagt.:


> Meinem Verständnis nach wäre Referenz ok.


Ja, ich meinte damit nur, wie wir (Pluralis Majestatis    - ok,  mit "wir" ist "wir in der Firma" gemeint) das in der Regel handhaben. Durch die Verwendung einer ID statt einer Objektreferenz wird eine völlig klare, harte Grenze gezogen. Bei einer Objektreferenz muss das referenzierte Objekt existieren, was zu einer entsprechenden Foreign Key Constraint in der DB führt. Das widerspricht meist dem Gedanken, die Aggregate unabhängig voneinander verarbeiten zu können.

Konkret würde es so aussehen, dass wir eine Klasse für Bestellpositionen hätten, die Teil des Aggregats "Bestellung" ist. In Bestellung gäbe es dann eine List<Bestellposition> (Fetch LAZY). Die Bestellposition würde alle Informationen enthalten, die für die Bestellung notwendig sind. Das Produkt (Artikel) würde dann per Artikelnummer (bzw. per zusätzlicher ID) referenziert. Somit kann es durchaus sein, dass ein in einer Bestellung vorhandenes Produkt gar nicht mehr im Produktkatalog existiert, trotzdem wird die Bestellung nach wie vor alle Informationen enthalten.


----------



## OnDemand (19. Aug 2020)

Danke, noch eine andere Frage die in eine ähnliche Richtung geht:

Angenommen ein Produkt hat eine Collection in der 100 Bilderlinks sind. Die Bilder gehören ja zum Artikel, sollten daher auch direkt mit dem Artikel verbunden sein. Wann aber macht es Sinn, dass ich zwei Objekte nicht mit einander verbinde per Relation. Doofe Frage aber angenommen ich lade das Produkt mittels Lazy, dann lädt es ja die 100 IDs der Bilder, die ich aber vielleicht gar nicht brauche. Wenn ich diese brauche kann ich sie auch über die product_id laden.

Zb in einem Frontend, werden 1000 Artikel angezeigt, jedes Produkt hat 1000 Bilder. Nun interessieren mich die Bilder aber gar nicht in der Artikelüberischt. Erst wenn ich auf das Produkt klicke um Details zu sehen, will ich die Bilder. Dann könnte ich "select * from images where product_id =xx" aufrufen um alle Bilder des gewählten Artikels zu laden zu erhalten.


----------



## mihe7 (19. Aug 2020)

Du kannst davon ausgehen, dass Du neben dem "Domain Model" ein "Query Model" hast. Diese können in vielen Punkten übereinstimmen, aber grundsätzlich stehen da zwei völlig verschiedene Anforderungen dahinter, die sich ggf. nicht mit einem Modell erschlagen lassen.



NicoDeluxe hat gesagt.:


> Erst wenn ich auf das Produkt klicke um Details zu sehen, will ich die Bilder. Dann könnte ich "select * from images where product_id =xx" aufrufen um alle Bilder des gewählten Artikels zu laden zu erhalten.


Das dürfte beim Lazy-Loading sowieso passieren. Allerdings sieht man hier eine weitere Problematik: wer braucht schon 1000 Bilder auf einen Schlag?


----------

