Paramètre d’instruction JDBC Prepared dans JSON

J’ai une table qui a une colonne de données avec une structure similaire à celle-ci:

{"title": "some title", "objects": [{"id": "id1"}, {"id": "id2"}]} 

Maintenant, je veux trouver toutes les lignes qui ont un object avec un identifiant spécifique dans leur tableau d’objects à l’intérieur des données. La requête suivante fonctionne parfaitement à partir de la console PSQL:

 SELECT id, data FROM table_name WHERE data->'objects' @> '[{"id": "id1"}]' 

Cependant, je ne peux pas obtenir que cela fonctionne comme une instruction préparée sur un pilote JDBC. la valeur de id devrait être un paramètre, j’ai donc essayé ceci en tant que chaîne transmise à connection.prepareStatement(query); :

 "SELECT id, data FROM table_name WHERE data->'objects' @> '[{\"id\": ?}]'" 

ici, quand j’essaie de définir des arguments, j’obtiens cette exception:

 org.postgresql.util.PSQLException: The column index is out of range: 1, number of columns: 0. 

Lorsque j’essaie l’un des arguments suivants, l’argument est correctement défini:

 "SELECT id, data FROM table_name WHERE data->'objects' @> [{\"id\": ?}]" "SELECT id, data FROM table_name WHERE data->'objects' @> [{'id': ?}]" 

mais le résultat n’est évidemment pas une requête correctement formatée:

 SELECT id, data FROM table_name WHERE data->'objects' @> [{"id": 'id1'}] SELECT id, data FROM table_name WHERE data->'objects' @> [{'id': 'id1'}] 

dans les deux cas j’obtiens l’exception suivante:

 org.postgresql.util.PSQLException: ERROR: syntax error at or near "[" 

Quelle est la syntaxe correcte pour définir un paramètre dans JSON? J’utilise PostgreSql 9.5

En fait, j’ai contacté les développeurs JDBC chez Github et, après quelques discussions, il semble qu’actuellement, la meilleure solution consiste à obtenir la déclaration préparée comme suit:

 Ssortingng query = "SELECT id, data FROM table_name WHERE data->'objects' @> ?::jsonb"; 

et transmettez l’intégralité des critères de recherche en tant qu’object JSON ssortingngifié pour le paramètre:

 PreparedStatement st = connection.prepareStatement(query); st.setSsortingng(1, "[\"id\":" + "id1" + "]"); st.executeQuery(); 

ce n’est pas une solution parfaite mais semble la meilleure possible en raison du manque de capacités du serveur. Au final, ce n’est pas si grave car il n’y a (théoriquement) aucun risque d’injection SQL.

Plus de détails sur le problème lié à Github.