@MappedSuperclass Probleme und Lösungsideen gesucht

HaukeG

Mitglied
Hallo zusammen,

ich suche eine Lösung für folgendes Problem:

Ich habe eine Tabelle "Person". Diese Tabelle hat zB folgende Felder:

vorname
nachname
strasse

Diese Datenbankstruktur hat zum Beispiel unser Kunde "A" für den ich jetzt eine Schnittstelle programmiere die Personen importiert. Daher hätte ich jetzt folgende Klasse geschrieben:

Java:
@Entity
@Table (name = "person")
public class Person {

  private String vorname;
  private String nachname;
  private String strasse;

  // getter und setter

}

In meiner Schnittstelle für Kunde "A" erzeuge ich dann eine neue Instanz

Java:
  Person person = new Person();

Soweit sogut.


Nun kommt Kunde "B" der eine neuere Datenbankversion (Schema) hat, wo zB noch das Feld
geburtstag
hinzugekommen ist. Dieser Kunde "B" möchte nun eine Schnittstelle haben, die die Personen exportiert. Daher habe ich gedacht ich könnte

Java:
public class Person2 extends Person {
   private Date geburtstag;

   // getter und setter
}

verwenden aber das funktioniert so nicht.
In einem Forum habe ich gelesen das es @MappedSuperclass gibt und das ich eine Art Basisklasse erzeugen sollte.

Java:
@MappedSuperclass
public abstract class PersonBase {
   private String vorname;
   private String nachname;
   private String strasse;
}

und dann immer eine neue Klasse implementieren die diese Baseklasse erweitert. Aber auch das funktioniert nicht wirklich.



Zum Hintergrund:
Leider können wir in der Firma nicht davon ausgehen das alle unsere Kunden das gleiche DB Schema haben. Selbst wenn ich eine neue Version von einer Schnittstelle bei einem Kunden einspiele kann es sein, dass das DB Schema noch in einer älteren Version vorhanden ist. Ich kann auch nicht einfach die neuen Felder hinzufügen, da sonst die Oberfläche verrückt spielt.

Vorher haben wir das so gelöst, dass wir verschiedene Mappings (*.hbm.xml) Dateien hatten und dann das jeweilige Mapping in der hibernate.cfg.xml eingetragen haben. Da wir nun aber auf einen Application Server umsteigen und mit EJBs arbeiten möchten, wollen wir von diesen Mappings weg die immer viel Arbeit gemacht haben.


Hat jemand eine gute Idee wie man sowas geschickt lösen kann?


Vielen dank für die Hilfe und einen schönen Abend noch,
Hauke
 

bluer

Aktives Mitglied
Wenn du aus deiner Klasse
Java:
public class Person2 extends Person {
   private Date geburtstag;
 
   // getter und setter
}
ebenfallse eine Entity machst, also @Entity annotierst, wird eine neue Tabelle in deine DB geschrieben die die PersonID enthält und deine gewünschte zusätzliche Information, hier Geburtstag. So habt ihr bei jedem Kunden eine "Standardtabelle" mit den Grundeinträgen wie Vor- und Zuname etc. und dann je nach Kunden noch eine Extratabelle wo die Zusatzinformationen stehen. Es kann somit für jeden Kunden die Klasse Person verwendet werden und man muss nur noch eine auf die Kundenwünsche angepasste Erweiterung implementieren.
 

AFlieger

Mitglied
Leider können wir in der Firma nicht davon ausgehen das alle unsere Kunden das gleiche DB Schema haben. Selbst wenn ich eine neue Version von einer Schnittstelle bei einem Kunden einspiele kann es sein, dass das DB Schema noch in einer älteren Version vorhanden ist. Ich kann auch nicht einfach die neuen Felder hinzufügen, da sonst die Oberfläche verrückt spielt.

Das erschließt sich mir nicht wirklich. Was hindert euch daran beides zeitgleich auszuliefern?
Ihr habt es doch in der Hand wann ihr was an den Kunden ausliefert.

Es hat doch jeder Kunde seine eigene Infrastruktur, sprich DB und AS oder nutzen alle Kunden einen zentralen AS und getrennte Datenbanken?
Ist letzteres der Fall, so werfe ich einfach mal OSGI in den Raum.

Bluers Vorschlag wird wohl funktionieren, aber wohin soll das führen? Zu mehreren 1:1 verknüpften Tabellen, mit jeweils nur einer Spalte?

Ich bin mir relativ sicher, dass dies der Gesamtperformance der Anwendung nicht gerade zuträglich ist.

Da würde ich schon eher bei dem Konfigurationshack mit der hbm.xml Datei bleiben.
 

bluer

Aktives Mitglied
Bluers Vorschlag wird wohl funktionieren, aber wohin soll das führen? Zu mehreren 1:1 verknüpften Tabellen, mit jeweils nur einer Spalte?
Dazu würde dies nicht führen. Bsp.: Man hat eine Grundklasse Person mit Informationenen, die immer benötigt werden. Nun wird je nach Kundenwunsch ein Klasse:
Java:
@Entity
public KundeBPerson extends Person{
...
}
implementiert mit diversen zusätzlichen Informationen. Am Ende hat man in der DB zwei Tabellen, eine Tabelle Person und eine weitere KundeBPerson mit geerbter Id und mit allen zusätzlichen Informationen in den Spalten.
 

AFlieger

Mitglied
Das ist schon klar. Aber die Anwendung besteht denke ich mal aus mehreren Tabellen, nicht nur aus Personen.

Und jetzt übertrage dieses Verfahren auf mehrere Anwendungsfälle. Nimm schon alleine mal weitere Fälle bezogen auf die Personen, so bist du hier leicht bei mehreren Tabellen, die gejoined werden müssen, um an die Informationen zu einer Person zu kommen.

Schon das hier gezeigte Beispiel erfordert einen OUTER-JOIN.
 
N

nillehammer

Gast
In JPA gibt es verschiedene Strategien, Inheritance zu mappen alle mit Vor- und Nachteilen. In der Hibernate Dokumentation ist das sehr gut beschrieben. Zum entspr. Kapitel geht's hier: HIBERNATE - Relational Persistence for Idiomatic Java
Gibt's notfalls auch in Deutsch.

Schon das hier gezeigte Beispiel erfordert einen OUTER-JOIN.
Das stimmt, das ist der Nachteil der Strategie "Joined Subclass". Vorteile sind, dass man damit eine Anforderung, wie die vom TO geschilderte, überhaupt erst umsetzen kann. Darüber hinaus sind mit dieser Strategie polymorphe Queries möglich. Was bei der sicher effizienteren -weil ohne Joins auskommenden- Strategie mit @MappedSuperclass schlicht nicht geht.
 

HaukeG

Mitglied
Hallo zusammen,

ich werde mir das morgen genau durchlesen. Habe heute keine Zeit gehabt nachzusehen. Vielen dank schonmal an alle!
 

Ähnliche Java Themen


Oben