Derby/JavaDB Datenbanktabelle erweitern, ohne Tabelle zu ändern

ProChris

Mitglied
Hallo zusammen,

als Interface zu meiner Datenbank nutze ich JPA und als konkrete Implementierung EclipseLink.

Ich würde gerne eine Tabelle erweiterbar machen. Zum Zeitpunkt der Entwicklung kenne ich leider noch nicht alle Anforderungen an die Datenbank Tabellen.

Beispiel:

Ich habe ein kleine Adressverwaltung geschrieben. Die Datenbanktabelle wie so aus:

Kontakte
IDVornameName
1Ich bin ein VornameIch bin ein Name
2Vorname bin ichName bin ich

Angenommen wir wollen jetzt einen weiteren Wert in der Tabelle speichern, ohne diese zu verändert. In der aktuellen Tabelle ist das nicht so einfach möglich. Ich habe mir dazu folgendes überlegt:

Eine zweite Tabelle anlegen, die auf die erste referenziert. Konkret sieht das so aus:

KontakteErweiterung
IDKontakteIDTypZahlZeichenketteDatum
11Geburtsdatum<null><null>20.01.2000
21Alter20<null><null>
31Telefonnummer<null>+49123456789<null>
42Geburtsdatum<null><null>01.01.2000
52Telefonnummer<null>+49987654321<null>

Mit der Tabelle KontakteErweiterung ist meine Tabelle Kontakte quasi endlos erweiterbar mit den drei Datentypen Zahl, Zeichenkette und Datum.

Gibt es eine Möglichkeit das mit JPA abzubilden? Wünschenswert wäre etwas, was so flexibel ist, dass man quasi jede beliebige Tabelle so weitern kann. Ich könnte mir sowas vorstellen:

Code:
public class Kontakte extends Erweiterung

Es wäre doch cool, wenn allein durch die Vererbung die DB Tabelle angelegt wird. Geht sowas irgendwie?

Viele Grüße

ProChris
 
Das klingt schon recht gut. Kann man das auch dynamisch umsetzen? Nach diesem Konzept müsste ich für jede Datenbanktabelle, die ich erweitern möchte eine eigene Klasse anlegen. Ich hätte gerne nur eine Erweiterung Klasse.

Beispiel:

Code:
public class Kontakte extends Erweiterung
public class Projekte extends Erweiterung
public class Kunden extends Erweiterung

Nach dem Beispiel muss ich für jede der Entität eine Erweiterungsklasse programmieren, weil die Annotation den Namen der Datenbanktabelle enthält: @Table(name="TABLENAME")
 
Hallo zusammen,

ich habe es geschafft. 🙂 Für alle die es interessiert, wir ich es gelöst habe.

Hier eine Klasse Kunden, die in der Datenbank die Tabelle Kunden mit drei Feldern anlegt. Die Felder sind: ID, VORNAME, NAME
Java:
@Entity
@Table(name = "KUNDEN")
public final class Kunden extends AbstractErweiterung
{
    private String nachname;

    private String vorname;

    public Kunden()
    {

    }

    public String getNachname() {
        return this.nachname;
    }

    public void setNachname(final String nachname) {
        this.nachname = nachname;
    }

    public String getVorname() {
        return this.vorname;
    }

    public void setVorname(final String vorname) {
        this.vorname = vorname;
    }
}

Diese abstrakte Klasse legt die *_ERWEITERUNG Tabelle an. In dieser Erweiterung Tabelle sind alle nützlichen Datentypen enthalten.

Java:
@MappedSuperclass
public abstract class AbstractErweiterung
{
    @Id
    private final String id;

    @ElementCollection
    @OneToMany
    private Map<String, ErweiterungWerte> erweiterung;

    protected AbstractErweiterung()
    {
        super();

        this.id = UUID.randomUUID().toString();
        this.erweiterung = new HashMap<>();
    }

    public void setStringWert(final String name, final String stringWert)
    {
        final ErweiterungWerte erweiterungWerte = new ErweiterungWerte();

        erweiterungWerte.setStringWert(stringWert);

        this.erweiterung.put(name, erweiterungWerte);
    }

    public String getStringWert(final String name)
    {
        return this.erweiterung.get(name).getStringWert();
    }
// ToDo: Alle anderen Methoden müssen noch hinzugefügt werden.
}

Java:
@Embeddable
public final class ErweiterungWerte
{
    private Boolean booleanWert;

    private Integer integerWert;

    private Double doubleWert;

    private String stringWert;

    private Date dateWert;

    public ErweiterungWerte()
    {

    }

    public Boolean getBooleanWert() {
        return this.booleanWert;
    }

    public void setBooleanWert(final Boolean booleanWert) {
        this.booleanWert = booleanWert;
    }

    public Integer getIntegerWert() {
        return this.integerWert;
    }

    public void setIntegerWert(final Integer integerWert) {
        this.integerWert = integerWert;
    }

    public Double getDoubleWert() {
        return this.doubleWert;
    }

    public void setDoubleWert(final Double doubleWert) {
        this.doubleWert = doubleWert;
    }

    public String getStringWert() {
        return this.stringWert;
    }

    public void setStringWert(final String stringWert) {
        this.stringWert = stringWert;
    }

    public Date getDateWert() {
        return this.dateWert;
    }

    public void setDateWert(final Date dateWert) {
        this.dateWert = dateWert;
    }
}

Was mich interessiert, seht ihr Verbesserungspotential?

Viele Grüße

ProChris
 
Alternativ kann man z.B. JSON nutzen, welches in modernen Datenbanken Einzug findet. Dann kann man den Dynamischen Teil beliebig erweitern.
 
Ich glaube auch nicht, dass das mit JPA Bordmitteln geht. Meine persönliche Meinung dazu ist: Das ist ein Datenbanklayout, was man tunlichst vermeiden sollte und der Normalisierung widerspricht.

Es ist unübersichtlich (weil die Daten zu einer Entität nicht in einer Tabellenzeile stehen sondern in mehreren) macht Querys deutlich komplexer (Liefere mir alle Daten zu allen Kontakten die mit Nachnamen Max heißen - dann bekomme ich gg. 50 Zeilen, wovon 30 zu Max Mustermann und 20 zu Max Müller gehören - dass muss ich mir dann aber in Java zusammenstricken, in der Datenbank geht das kaum).

Sinnvoll ist das meines Erachtens nur, wenn ich diese Daten, die ich in der Erweiterung speichere nicht fest in meinen Klassen habe, sondern die dynamscih zur Laufzeit angelegt werden (z.B. in einer Key/Value Map). Dann wiederrum muss ich mir aber überlegen, wie ich in Map in JPA speichere. Darüber könnte man dass ggf. lösen. Aber wenn ich die Werte wirklich als fixe Variablen habe, dann gehören die auch in die Kontakte Tabelle rein und die Tabelle um die Spalten erweitert.
 

Neue Themen


Zurück
Oben