Proč se to děje
Problém je v tom, že PostgreSQL je příliš striktní ohledně přetypování mezi textovými a netextovými datovými typy. Nepovolí implicitní přetypování (bez CAST
nebo ::
v SQL) z textového typu jako text
nebo varchar
(character varying
) na textový netextový typ, jako je json
, xml
, atd.
Ovladač PgJDBC specifikuje datový typ varchar
když zavoláte setString
pro přiřazení parametru. Pokud databázový typ sloupce, argument funkce atd. ve skutečnosti není varchar
nebo text
, ale místo jiného typu se zobrazí chyba typu. To platí také pro mnoho dalších ovladačů a ORM.
PgJDBC:stringtype=unspecified
Nejlepší možností při použití PgJDBC je obecně předat parametr stringtype=unspecified
. Toto přepíše výchozí chování předávání setString
hodnoty jako varchar
a místo toho ponechává na databázi, aby „uhádla“ jejich datový typ. Téměř ve všech případech to dělá přesně to, co chcete, předáním řetězce do validátoru vstupu pro typ, který chcete uložit.
Vše:CREATE CAST ... WITH FUNCTION ...
Místo toho můžete CREATE CAST
k definování specifického přetypování datového typu, které to umožní na základě typu po typu, ale to může mít vedlejší účinky jinde. Pokud to uděláte, nedělejte to použijte WITHOUT FUNCTION
přetypování, obejdou ověření typu a způsobí chyby. Pro datový typ musíte použít funkci input/validation. Pomocí CREATE CAST
je vhodný pro uživatele jiných databázových ovladačů, kteří nemají žádný způsob, jak zastavit ovladač specifikující typ pro řetězcové/textové parametry.
např.
CREATE OR REPLACE FUNCTION json_intext(text) RETURNS json AS $$
SELECT json_in($1::cstring);
$$ LANGUAGE SQL IMMUTABLE;
CREATE CAST (text AS json)
WITH FUNCTION json_intext(text) AS IMPLICIT;
Vše:Obslužný program vlastního typu
Pokud to vaše ORM dovoluje, můžete implementovat vlastní popisovač typu pro datový typ a konkrétní ORM. To je většinou užitečné, když používáte nativní typ Java, který se dobře mapuje na typ PostgreSQL, místo použití String
, i když to může také fungovat, pokud vám váš ORM umožňuje specifikovat obslužné rutiny typu pomocí anotací atd.
Metody implementace obslužných rutin vlastního typu jsou specifické pro ovladač, jazyk a ORM. Zde je příklad pro Java a Hibernate pro json
.
PgJDBC:zadejte obslužný program pomocí PGObject
Pokud v Javě používáte nativní typ Java, můžete rozšířit PGObject
poskytnout mapování typu PgJDBC pro váš typ. Pravděpodobně budete také muset implementovat obslužný program typu specifický pro ORM, abyste mohli používat váš PGObject
, protože většina ORM bude volat pouze toString
na typy, které neznají. Toto je preferovaný způsob mapování komplexních typů mezi Java a PostgreSQL, ale také nejsložitější.
PgJDBC:Zadejte obslužný program pomocí setObject(int, Object)
Pokud používáte String
pro uchování hodnoty v Javě, místo specifičtějšího typu, můžete vyvolat metodu JDBC setObject(integer, Object)
pro uložení řetězce bez zadaného konkrétního datového typu. Ovladač JDBC odešle reprezentaci řetězce a databáze odvodí typ z typu cílového sloupce nebo typu argumentu funkce.
Viz také
Otázky:
- Mapování sloupce postgreSQL JSON na typ hodnoty Hibernate
- Jsou možné vlastní typy JPA (EclipseLink)?
Externí:
- http://www.postgresql.org/message-id/[email protected]
- https://github.com/pgjdbc/pgjdbc/issues/265
- http://www.pateldenish.com/2013/05/inserting-json-data-into-postgres-using-jdbc-driver.html