PostgreSQL
 sql >> Base de données >  >> RDS >> PostgreSQL

Postgres UUID JDBC ne fonctionne pas

tl;dr

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

Détails

(a) Montrez-nous votre code.

PreparedStatement::setObject fonctionne lors du passage d'un java.util.UUID . Vous avez probablement un autre problème dans votre code.

(b) Voir mon article de blog UUID Values ​​From JDBC to Postgres pour un peu de discussion et un exemple de code.

// 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) Je ne suis pas sûr de ce que vous entendez par

Les derniers pilotes Java JDBC pour postgres prétendent prendre en charge les UUID de manière native

Quel chauffeur ? Il existe au moins deux pilotes JDBC open-source pour Postgres, l'actuel/ancien et un nouveau pilote de réécriture de "nouvelle génération". Et il y a aussi d'autres chauffeurs commerciaux.

"nativement" ? Pouvez-vous faire un lien vers la documentation que vous avez lue? La spécification SQL n'a pas de type de données pour UUID (malheureusement ☹), donc la spécification JDBC n'a pas de type de données pour UUID. Comme solution de contournement, le pilote JDBC pour Postgres utilise le setObject et getObject Les méthodes sur PreparedStatement déplacent l'UUID à travers le gouffre entre Java ↔ SQL ↔ Postgres. Voir l'exemple de code ci-dessus.

Comme le dit la documentation JDBC de PreparedStatement :

Si des conversions de types de paramètres arbitraires sont nécessaires, la méthode setObject doit être utilisée avec un type SQL cible.

Peut-être par "nativement", vous avez confondu le support natif de Postgres pour UUID en tant que type de données avec JDBC ayant un type de données UUID. Postgres prend en effet en charge UUID en tant que type de données, ce qui signifie que la valeur est stockée sous forme de 128 bits plutôt que plusieurs fois si elle était stockée sous forme de chaîne hexadécimale ASCII ou Unicode. Et être natif signifie également que Postgres sait comment créer un index sur une colonne de ce type.

Le point de mon article de blog mentionné ci-dessus était que j'ai été agréablement surpris par la simplicité avec laquelle il est possible de combler ce gouffre entre Java ↔ SQL ↔ Postgres . Lors de mes premières tentatives sans instruction, je travaillais trop dur.

Une autre note sur Postgres prenant en charge l'UUID… Postgres sait comment stocker, indexer et récupérer les valeurs UUID existantes. Pour générer Valeurs UUID, vous devez activer l'extension Postgres (plugin) uuid-ossp . Cette extension encapsule une bibliothèque fournie par le projet OSSP pour générer une variété de types de valeurs UUID. Voir mon blog pour les instructions.

Au fait…

Si je savais comment demander au groupe d'experts JDBC ou à l'équipe JSR de sensibiliser JDBC à l'UUID, je le ferais certainement. C'est exactement ce qu'ils font pour les nouveaux types date-heure définis dans JSR 310 :API de date et d'heure.

De même, si je savais comment demander au comité des normes SQL d'ajouter un type de données UUID, je le ferais. Mais apparemment, ce comité est plus secret que le Politburo soviétique et plus lent qu'un glacier.