# @Embeddable oder @MappedSuperClass ?



## ayibogan (15. Dez 2010)

Hallo,
wie der Titel schon sagt, beschäftigt mich die Frage wann welche Annotation sinnvol ist. Funktionieren tun ja beide 

Hätte 2 Fragen dazu.
1. Für Bsp. unten. Ziel ist es eine "Oberklasse" für realtiv viele Entites (die alle als Basis die gleichen Attribute haben) zu erstellen, ohne die "Oberklasse" selbst als Entity nutzen zu wollen.
2. Wann wäre allg. @Embeddable oder @MappedSuperClass sinvoll.

Dankbar für alle Infos.



```
@MappedSuperclass
public class Person{
  String name
  ...
}


@Entity
public class Student extends Person{
  @Id
  protected long id
  ...
}
```

oder 


```
@Embeddable
public class Person{
  String name;
  ...
}

@Entity
public class Student{
  @Id
  protected long id
  ...
}
```


----------



## KSG9|sebastian (16. Dez 2010)

Da ist doch ein grundlegender Unterschied zwischen beiden Annotationen.

@Embeddable ist dafür da um eine 1:1-Referenz in derselben Tabelle zu speichern.

Zum Beispiel Person-Adresse

```
@Embeddable
class Adresse{
   String ort
}
@Entity
class Person{
  String name
   
  @Embedded
  Adresse adresse
}
```

Auf der Datenbank sieht es dann so aus:

```
Tabelle Person

person_name  |  adresse_ort
```

Ziel des ganzen ist oftmals die Anzahl der Tabellen nicht zu erhöhen und trotzdem im Objektmodel die objektorientierte Struktur zu erhalten. Meist wird es bei Daten gemacht welche im Sinne von OO aufgeteilt werden in zwei Klassen, jedoch immer als Paar auftreten.
Bsp oben: Eine Person *muss* eine Adresse haben. Aus Sicht der OO sind es aber zwei verschiedene Entitäten.
Auf Datenbankseite macht es Sinn die Daten in eine Tabelle zu legen um die Performance zu erhöhen (ein JOIN fällt weg).

Wird oftmals verwendet um die Datenbank zu "schonen". Normalisierung ist zwar schön und gut, aber man muss hier bei sehr großen Datenmengen aufpassen das man es nicht übertreibt. 40 Joins mehr nur auf Kosten der Normalisierung ist unnötig, deshalb wird hier oft ein guter Mittelweg gewählt


@MappedSuperclass dient dazu um persistente Klassen mit Attributen anzureichern welche immer gebraucht werden, z.B. Ersetllungsdatum, technische Informationen, fachliche Schlüssel. Dafür wird eine Klasse mit diesen Attributen definiert und alle persistenten Klassen erben davon. Da die Superklasse aber nirgends alleine auftaucht und auch als Entity nicht bekannt sein soll wird der Ansatz als MappedSuperclass verwendet. Die anderen Vererbungsstrategien (Table per Class, Table per Hierarchy, Join Table) bringen hier nicht die gewünschte Lösung bzw sind durch die Umsetzung z.B. über Diskriminator, mehrere Tabellen deutlich langsamer und meist auch unsinnig.


* Edit *

- MappedSuperclass wird für Vererbung verwendet
- Embeddable/Embedded wird für 1:1-Referenzen verwendet

In deinem Beispiel:
- Stundent ist eine Person - somit MappedSuperclass

Embedded hilft dir nicht weiter denn es würde ja bedeuten das ein Stundent eine Person hat. Ist zwar sicher auch sinnvoll, z.B. Student hat einen Lehrer, aber ist fachlich etwas komplett anderes.

Stundent ist eine Person != Stundent hat eine Person

Stundent ist eine Person = Vererbung, MappedSuperclass, Table per Class, Table per Concret Class, Table per Hierarchie
Stundent hat eine Person = One To One, Embedded


----------



## ayibogan (16. Dez 2010)

Danke für die Antwort, werd mir das ma genauer durch den Kopf gehen lassen.


----------

