PostgreSQL
 sql >> Datenbank >  >> RDS >> PostgreSQL

Postgres UUID JDBC funktioniert nicht

tl;dr

myPreparedStatement.setObject( 
    … , 
    java.util.UUID.randomUUID()
)

Einzelheiten

(a) Zeigen Sie uns Ihren Code.

PreparedStatement::setObject funktioniert, wenn eine java.util.UUID übergeben wird . Sie haben wahrscheinlich ein anderes Problem in Ihrem Code.

(b) Siehe meinen Blogbeitrag UUID Values ​​From JDBC to Postgres für ein wenig Diskussion und Beispielcode.

// Generate or obtain data to store in database.
java.util.UUID uuid = java.util.UUID.randomUUID(); // Generate a random UUID. 
String foodName = "Croissant";
// JDBC Prepared Statement.
PreparedStatement preparedStatement = conn.prepareStatement( "INSERT INTO food_ (pkey_, food_name_  ) VALUES (?,?)" );
int nthPlaceholder = 1; // 1-based counting (not an index).
preparedStatement.setObject( nthPlaceholder++, uuid ); 
preparedStatement.setString( nthPlaceholder++, foodName ); 
// Execute SQL.
if ( !( preparedStatement.executeUpdate() == 1 ) ) { 
  // If the SQL reports other than one row inserted…
  this.logger.error( "Failed to insert row into database." );
}

(c) Ich bin mir nicht sicher, was Sie mit

meinen

Die neuesten Java-JDBC-Treiber für Postgres behaupten, UUIDs nativ zu unterstützen

Welcher Fahrer? Es gibt mindestens zwei Open-Source-JDBC-Treiber für Postgres, den aktuellen/alten und einen neu geschriebenen „nächsten Generation“. Und es gibt auch andere kommerzielle Fahrer.

"nativ"? Können Sie auf die Dokumentation verlinken, die Sie gelesen haben? Die SQL-Spezifikation hat keinen Datentyp für UUID (leider ☹), daher hat die JDBC-Spezifikation keinen Datentyp für UUID. Als Problemumgehung verwendet der JDBC-Treiber für Postgres das setObject und getObject Methoden auf PreparedStatement verschieben die UUID über die Kluft zwischen Java ↔ SQL ↔ Postgres. Siehe Beispielcode oben.

Wie das PreparedStatement JDBC-Dokument sagt:

Wenn beliebige Parametertypkonvertierungen erforderlich sind, sollte die Methode setObject mit einem Ziel-SQL-Typ verwendet werden.

Vielleicht haben Sie durch "nativ" die native Unterstützung von Postgres für UUID als Datentyp mit JDBC mit einem UUID-Datentyp verwechselt. Postgres unterstützt tatsächlich UUID als Datentyp, was bedeutet, dass der Wert als 128-Bit gespeichert wird und nicht mehrfach als wenn er als ASCII- oder Unicode-Hex-String gespeichert würde. Und nativ zu sein bedeutet auch, dass Postgres weiß, wie man einen Index für eine Spalte dieses Typs erstellt.

Der Punkt meines oben erwähnten Blogbeitrags war, dass ich angenehm überrascht war, wie einfach es ist, diese Kluft zwischen Java ↔ SQL ↔ Postgres zu überbrücken . Bei meinen ersten ungebildeten Versuchen habe ich zu hart gearbeitet.

Noch ein Hinweis zur Unterstützung von UUID durch Postgres … Postgres weiß, wie man vorhandene UUID-Werte speichert, indiziert und abruft. Zum Generieren UUID-Werte müssen Sie die Postgres-Erweiterung (Plugin) uuid-ossp aktivieren . Diese Erweiterung umschließt eine von The OSSP Project bereitgestellte Bibliothek zum Generieren verschiedener Arten von UUID-Werten. In meinem Blog finden Sie Anweisungen.

Übrigens…

Wenn ich wüsste, wie ich bei der JDBC-Expertengruppe oder dem JSR-Team eine Petition einreichen könnte, um JDBC auf UUID aufmerksam zu machen, würde ich es sicherlich tun. Sie tun genau das für die neuen Datums-Zeit-Typen, die in JSR 310:Date and Time API.

definiert werden

Wenn ich wüsste, wie ich beim SQL-Standardskomitee eine Petition einreichen könnte, um den Datentyp UUID hinzuzufügen, würde ich es tun. Aber anscheinend ist dieses Komitee geheimnisvoller als das sowjetische Politbüro und langsamer als ein Gletscher.