Alte Daten ins neue Modell quetschen

  • Themenstarter Themenstarter Gelöschtes Mitglied 68249
  • Beginndatum Beginndatum
G

Gelöschtes Mitglied 68249

Gast
Hallo zusammen,

ich habe folgendes Problem:
Ich habe ein neues Datenmodell zu einer alten Anwendung erstellt. Die neue Tabelle ist (ich denke mal) ziemlich gut nach dem relationalen Standard, d.h. Werte, die der Benutzer besser nicht eingibt, sondern auswählt, sind entweder in einem ENUM, oder eben relational verknüpft in einer weiteren Tabelle.

Die alte Anwendung war da ein wenig anders. Erstmal waren alle "Spalten" untereinander, d.h. für jedes Feld gab es eine Zeile mit ID und Feldindex als Schlüssel. Zusätzlich sind damit alle Werte erstmal String. Verknüpfungen sind auch eher katastrophal aufgelöst worden.

Jetzt hat der Kunde angefordert, dass zur Einarbeitung die User bitte vor der Migration auf die alte Datenbank zugreifen sollen.

Grundsätzlich für "einfache" Daten kein Problem. Ich habe also ein riesiges Select, dass mir die vertikalen Daten horizontal darstellt und als Alias den Feldnamen verwendet, den ich in der neuen Tabelle vorgesehen habe. Funktioniert aktuell auch topp für diese einfachen Felder. Problematisch sind jetzt aber die relationalen Felder. Also da, wo ich in meinem Datenmodell ein Objekt erwarte, kommt ja aus meiner neuen Datenbank eine ID, mit der er in einer anderen Tabelle einen Datensatz laden kann. Aus der alten Datenbank kommt aber ein "richtiger" Wert als String, also z.B. die Nummer eines Mandanten, die aber nicht die ID ist. Das knallt natürlich beim Laden der Daten, weil JPA mit dem String aus der alten DB keine Relation zur neuen Tabelle herstellen kann.

In meinem Kopf wäre die einfachste Lösung, wenn ich den String aus der alten Datenbank einfach in der Spalte für die MandantenID suchen würde und diese dann verwende. Dafür habe ich versucht einen jakarta.persistence.AttributeConverter zu schreiben. Dieser wird aber scheinbar zur Ladezeit nicht gezogen. Also habe ich versucht ihn in der Entity-Klasse ein zu bauen:
Java:
//    @ManyToOne
//    @JoinColumn(name = "TRANSMISSION_TYPE", referencedColumnName = "UUID" )
    @Column
    @Convert(converter = KeyTabConverter.class)
    private KeyValue transmissionType;
auskommentiert mal den richtigen Code, für die neue Implementierung.

Dann erhalte ich beim Serverstart aber folgenden Fehler:
Code:
[FEHLER  ] CWOWB1000E: Es ist ein CDI-Fehler aufgetreten: CWNEN0030E: Beim Abrufen der Objektinstanz des Bindungsobjekts jakarta.persistence.PersistenceException: Ausnahme [EclipseLink-28018] (Eclipse Persistence Services - 3.0.3.v202208190922): org.eclipse.persistence.exceptions.EntityManagerSetupException
Beschreibung der Ausnahme: Die Vorabimplementierung der Persistenzeinheit [nonManagedAtc] ist fehlgeschlagen.
Interne Ausnahme: Ausnahme [EclipseLink-7353] (Eclipse Persistence Services - 3.0.3.v202208190922): org.eclipse.persistence.exceptions.ValidationException
Beschreibung der Ausnahme: Das Zuordnungsattribut [transmissionType] der Klasse [main.java.proips.persistence.entities.WindowsOrder] ist kein gültiger Zuordnungstyp für eine Konvertierungsspezifikation. ist bei der Factory java:comp/env/main.java.timer.persistence.interfaces.NonTXJobScheduleDAO/emf ein Fehler aufgetreten. Ausnahmenachricht: {2}

Ich habe auch gerade beim Testen noch gesehen, wenn ich das Feld nicht nulle in der "richtigen" Implementierung, dann wirft er den Fehler:
Java:
[WARNUNG ] CWWJP9991W: Ausnahme [EclipseLink-4002] (Eclipse Persistence Services - 3.0.3.v202208190922): org.eclipse.persistence.exceptions.DatabaseException
Interne Ausnahme: com.microsoft.sqlserver.jdbc.SQLServerException: Ungültiger Objektname "S_KEYTAB".
Fehlercode: 208
Aufruf: SELECT UUID, ACTIVE, DISPLAYNAME, KEYNAME, KEYRANGE FROM S_KEYTAB WHERE (UUID = ?)
    bind => [SLcM]
Abfrage: ReadObjectQuery(name="transmissionType" referenceClass=KeyValue )
Weil er die Tabelle S_KEYTAB in der alten Datenbank sucht, da gibt es die Tabelle aber nicht, weil da die Werte einfach als String in der eigenen Tabelle abgelegt werden.

Also ist meine Frage:
wie sollte ich den Converter richtig einbauen.

Ich bin aber auch offen für alternative Vorschläge, wie ich die Daten vielleicht mit einem Ansatz darstellen kann, an den ich gerade nicht denke.
 
Zuletzt bearbeitet von einem Moderator:
Ich überlege gerade, ob es sinnvoll wäre an der Stelle eine implizite Migration zu machen?
Also die Suche sucht im Altsystem und wenn der User sich einen Datensatz auswählt, dann wird nicht dieser geöffnet, sondern er wird in die neue Datenbank geladen und dann von dort aus geöffnet.
Dann könnten die Relationen bleiben und in der Ansicht funktioniert alles, wie es soll.
Alle Relationen werden mit dazu geladen, vielleicht im ersten Schritt nur so weit, wie benötigt, z.B. bei verknüpften Windows Hosts nur der Name, der im Feld angezeigt wird.
Wenn ein Datensatz öfter als einmal geöffnet wird, dann wird er anhand seiner ID immer wieder überschrieben.
Solange die Daten noch nicht migriert sind, müsste ich zumindest nicht sämtliche Mechanismen verbiegen. Und aktuell ist im neuen System kein Speichern vorgesehen.
 
Käme ja im Endeffekt auf dasselbe raus, wie ein angepasstes SQL und am Ende bleibt das Problem mit den neuen Relationen.
 
Ende bleibt das Problem mit den neuen Relationen
Nein wieso, in der View würdest du schon die ID's verwenden - als ob alle Relationen vorhanden wären.. Es gibt die Relationen/FK's zwar nicht physisch, das stört aber das Programm nicht, wenn du nicht speicherst.
Ich würde ein Synonym auf die View erstellen, meinetwegen MEINE_TABELLE. Wenn ich die View dann nicht mehr brauche würde ich das Synonym löschen und neu anlegen - dann aber nicht mehr auf die View zeigen, sondern auf die echte Tabelle.
Im Programm muss nichts geändert werden und es funktioniert mit den alten und neuen Daten. Synonyme für Datenbankobjekte sind bei uns ganz normales Vorgehen.

SQL:
CREATE SYNONYM MEINE_TABELLE FOR ALTE_DATEN_VIEW;
-- später
DROP SYNONYM MEINE_TABELLE;
CREATE SYNONYM MEINE_TABELLE FOR NEUE_DATEN_TABELLE;
 
Okay, bin mir gerade nicht sicher, ob das klappt, weil die Keys sind in einer anderen Datenbank, sogar ein komplett anderes DBMS, anderer Server und ich meine sogar durch FW getrennt voneinander, also meine Anwendung wäre das Bindeglied zwischen den beiden Datenbanken. Aber an eine ähnliche Lösung hatte ich auch schon gedacht.
 

Zurück
Oben