JPA coloumnDefinition zur Laufzeit ändern

muRuS

Mitglied
Hallo Leute,

hoffe bin im richtigen Unterforum. =) Ich habe eine Anwendung, die auf eine Datenbank zugreift. Diese kann entweder auf einem PostgreSQL Server oder MS-SQL Server liegen. Ich möchte nun beim Login auswählen, um welche Art sich der Server dabei handelt. Das Problem ist, dass bei PostgreSQL BYTE-Felder als bytea (@Column(columnDefinition="bytea") private byte[] test) abgespeichert werden und bei MS-SQL als VARBINARY(8000) (@Column(columnDefinition="VARBINARY(8000)") private byte[] test). Ich würde halt gerne eine Variable dort setzen (columnDefinition=serverArt), aber die muss leider final sein. Beim Laden des Logins werden im Prinzip ja schon die Entity-Klassen geladen, auch wenn man noch nicht mit dem Server verbunden ist. Gibt es Kniffe, um das doch noch zur Laufzeit wählen zu können und man diese Klassen einfach "nachladen" kann?

Danke im Voraus :applaus:
muRuS
 

Barista

Top Contributor
Ich habe kurz nachgelesen, JPA arbeitet mit Gettern und Settern.

Du könntest also ein Datenbank-Typ-übergreifendes Interface definieren und je nach DB die entsprechenden Klassen verwenden.

Im Anwendungscode wäre der DB-Typ zumindest ausserhalb von DAO-Klassen / Repository-Klassen vom Typ der DB unabhängig.

Ich weiß nicht, ob dann noch weitere Probleme auftauchen.

Musst Du einfach ausprobieren.
 

muRuS

Mitglied
Erstmal danke. Klingt interessant. Aber ich weiss jetzt nicht ob ich das richtig verstanden habe. Ich kopiere zunächst meine Entitäts-Klasse und habe dann zweimal die selbe Klasse. Einmal mit bytea und einmal mit VARBINARY. Diese implementieren dann mein Interface, das alle Methoden dieser Klasse beinhaltet. Ich müsste im gesamten Code dann statt auf die Entität selbst auf dieses Interface zugreifen, richtig? Wie zwinge ich dann das Programm die eine oder die andere Klasse zu verwenden. Steh grad aufm Schlauch.
 
Zuletzt bearbeitet:

Barista

Top Contributor
Wenn Du DAO-Klassen oder Repsoitory-Klassen hast, dann haben diese zum Beispiel eine readEntity-Methode

JPA (Java Persistence API) - Torsten Horn

Java:
    public <T> T readEntity( Class<T> clss, Object id )
   {
      EntityManager em = emf.createEntityManager();
      try {
         return em.find( clss, id );
      } finally {
         em.close();
      }
   }

Als Parameter clss übergibts Du die jeweilige Klasse, in einem if entscheidest Du, welche Klasse.

Später kannst Du das noch schön machen mit einer Factory.
 

muRuS

Mitglied
Hi,

danke für den Link. Da stehen einige praktische Tipps drin. :)
Jetzt weiss ich was du meinst. Das wird aber nicht klappen. Ich habe rausgefunden, dass es zunächst egal ist, was bei der columnDefinition drin steht, wenn die Tabellen bereits existieren. Erst wenn man auf eine leere Datenbank verbindet und mittesl create-tables in der persistence.xml die neuen Tabellen von JPA erstellen lassen möchte, dann "guckt" er auf die columnDefinition und wirft dann einen Fehler (zb. VARBINARY existiert nicht bei PostgreSQL). Sprich es hat nicht mit den Gettern und Settern zutun. Das Getten und Setten mache ich ja erst später zur Laufzeit. Ich wüsste echt nicht wie man das dann anstellen soll. Schade dass man MSSQL den Datentyp "bytea" oder PostgreSQL den Datentyp "VARBINARY()" nicht "beibringen" kann. Oder? :bahnhof:
 

Barista

Top Contributor
Jetzt weiss ich was du meinst. Das wird aber nicht klappen. Ich habe rausgefunden, dass es zunächst egal ist, was bei der columnDefinition drin steht, wenn die Tabellen bereits existieren. Erst wenn man auf eine leere Datenbank verbindet und mittesl create-tables in der persistence.xml die neuen Tabellen von JPA erstellen lassen möchte, dann "guckt" er auf die columnDefinition und wirft dann einen Fehler (zb. VARBINARY existiert nicht bei PostgreSQL).

Du musst in einer Konfiguration(-sdatei) oder über einen Start-Parameter den Typ der Datenbank an das Programm übergeben.

Eine Alternative wäre das Auslesen der Database-Metadata:

JDBC DatabaseMetaData.getDatabaseProductName

Dafür kannst Du aber nicht JPA nutzen (ich kenne das aber nicht so genau, dass ich Dir sagen kann, ob es da auch so einen Aufruf gibt) sondern musst direkt JDBC benutzen.
 

muRuS

Mitglied
Hi,

das funktioniert leider alles nicht. Wenn ich statt @Column(columnDefinition = "bytea") so etwas schreibe wie @Column(columnDefinition = TestApp.bytetype) und die TestApp etwa so einen Inhalt hat:
Code:
static public String bytetype;

public static void main(String[] args) {

        if(args.length==1 && args[0].equals("-postgresql")){
            TestApp.bytetype = "bytea";
        }else{
            TestApp.bytetype = "VARBINARY(8000)";
        }
        launch(TestApp.class, args);
    }

...dann sagt er mir, dass bytetype halt final sein soll. Wenn ich das mache, dann muss ich logischerweise bei der Deklaration den Wert schon angeben und kann nicht erst beim Start den Parameter prüfen und dann eine finale Variable initalisieren. Ist halt final. Wie ich es auch drehe und wende. Es will wohl einfach nicht. Ich kann den bytetype halt nur hardcoded setzen und zwei Programme bauen. Eins für Postgre und eins für MSSQL. :(

Ist aber auch nicht ganz so schlimm. :)
Trotzdem danke für die Hilfe.

muRuS
 
Zuletzt bearbeitet:
Ähnliche Java Themen
  Titel Forum Antworten Datum
G Laufzeit Bestimmung mittels Landau Symbolic Datenbankprogrammierung 13
G Laufzeit eines Algorithmus mittels Big Theta bestimmen Datenbankprogrammierung 5
T importierte Derby DB währen der Laufzeit einlesen Datenbankprogrammierung 2
S persistence.xml zur Laufzeit manipulieren Datenbankprogrammierung 0
Psypsy Dynamisch zur Laufzeit Datenbank erzeugen Datenbankprogrammierung 2
C Hybernate DB zur Laufzeit wechseln Datenbankprogrammierung 4
Gossi Datenbank zur laufzeit wechseln... Datenbankprogrammierung 2
Y Hibernate - externe Datenbank zur Laufzeit ansprechen Datenbankprogrammierung 5
M mySQL zugriff funktionert nach ca4 stündiger laufzeit nicht Datenbankprogrammierung 6
M Meine Datenbank lässt sich mit meiner Methode nicht ändern Datenbankprogrammierung 1
S Oracle DB-Connection in .jar file ändern Datenbankprogrammierung 11
P Derby/JavaDB JPA Reihenfolge Spalten ändern Datenbankprogrammierung 6
P Derby/JavaDB Datenbanktabelle erweitern, ohne Tabelle zu ändern Datenbankprogrammierung 6
M MySQL Passwort Clientseitig ändern und über Button ausführen Datenbankprogrammierung 0
D Datumsformat auf DD.MM.YYYY ändern Datenbankprogrammierung 2
D Abfrage - Spalte(Datum) ändern (Oracle) Datenbankprogrammierung 7
D Datumsformat aus MySQL ändern Datenbankprogrammierung 15
X MySQL In MySQL Funktionen erstellen, wenn Zelle leer dann andere Zelle ändern? Datenbankprogrammierung 9
B MySQL: Port ändern über GUI? Wo und wie Port ändern? Datenbankprogrammierung 0
Neumi5694 MS Access Tabellenbesitzer ändern Datenbankprogrammierung 0
F MySQL Daten ändern über Java Datenbankprogrammierung 3
N Derby/JavaDB Bei PS das übergebene Datum ändern Datenbankprogrammierung 3
S JPA: DB Schema ändern und Daten nicht verlieren - wie? Datenbankprogrammierung 5
S Java/Hibernate: DB-Passwort ändern Datenbankprogrammierung 4
G PostgreSQL Postgre: Passwort eines Benutzers ändern Datenbankprogrammierung 3
M JTable änderung sofort auch in MySQL ändern. Datenbankprogrammierung 7
L Derby Dezimal-Spalte die Größe ändern Datenbankprogrammierung 2
L Struktur einer vorhandenen Datenbanktabelle ändern Datenbankprogrammierung 8
L Spaltentyp in MySQL ändern Datenbankprogrammierung 3
P [Hibernate] Objekt laden, Id ändern und speichern? Datenbankprogrammierung 2
M Primary Key ändern Datenbankprogrammierung 6

Ähnliche Java Themen


Oben