Waarom het gebeurt
Het probleem is dat PostgreSQL te streng is wat betreft casts tussen tekst- en niet-tekstgegevenstypen. Het staat geen impliciete cast toe (een zonder een CAST
of ::
in de SQL) van een teksttype zoals text
of varchar
(character varying
) naar een tekstachtig niet-teksttype zoals json
, xml
, enz.
Het PgJDBC-stuurprogramma specificeert het gegevenstype van varchar
wanneer je setString
. aanroept om een parameter toe te wijzen. Als het databasetype van de kolom, het functieargument, enz. in feite niet varchar
is of text
, maar in plaats daarvan een ander type, krijg je een typefout. Dit geldt ook voor heel wat andere stuurprogramma's en ORM's.
PgJDBC:stringtype=unspecified
De beste optie bij het gebruik van PgJDBC is over het algemeen om de parameter stringtype=unspecified
door te geven . Dit overschrijft het standaardgedrag van het doorgeven van setString
waarden als varchar
en laat het in plaats daarvan aan de database over om hun gegevenstype te "raden". In bijna alle gevallen doet dit precies wat je wilt, de string doorgeven aan de invoervalidator voor het type dat je wilt opslaan.
Alle:CREATE CAST ... WITH FUNCTION ...
U kunt in plaats daarvan CREATE CAST
om een datatype-specifieke cast te definiëren om dit per type mogelijk te maken, maar dit kan elders bijwerkingen hebben. Als je dit doet, doe dan niet gebruik WITHOUT FUNCTION
casts, zullen ze typevalidatie omzeilen en resulteren in fouten. U moet de invoer-/validatiefunctie voor het gegevenstype gebruiken. CREATE CAST
gebruiken is geschikt voor gebruikers van andere databasestuurprogramma's die geen manier hebben om te voorkomen dat het stuurprogramma het type voor tekenreeks-/tekstparameters specificeert.
bijv.
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;
Alle:handler voor aangepast type
Als uw ORM het toelaat, kunt u een aangepaste typehandler implementeren voor het gegevenstype en die specifieke ORM. Dit is vooral handig wanneer u het native Java-type gebruikt dat goed overeenkomt met het PostgreSQL-type, in plaats van String
, hoewel het ook kan werken als je ORM je type-handlers laat specificeren met behulp van annotaties enz.
Methoden voor het implementeren van aangepaste type-handlers zijn specifiek voor stuurprogramma's, talen en ORM's. Hier is een voorbeeld voor Java en Hibernate voor json
.
PgJDBC:type handler met behulp van PGObject
Als u een native Java-type in Java gebruikt, kunt u PGObject
. uitbreiden om een PgJDBC-typetoewijzing voor uw type te bieden. U zult waarschijnlijk ook een ORM-specifieke type-handler moeten implementeren om uw PGObject
te gebruiken. , aangezien de meeste ORM's gewoon toString
aanroepen op typen die ze niet herkennen. Dit is de geprefereerde manier om complexe typen tussen Java en PostgreSQL in kaart te brengen, maar ook de meest complexe.
PgJDBC:Type-handler met behulp van setObject(int, Object)
Als je String
. gebruikt om de waarde in Java vast te houden, in plaats van een specifieker type, kunt u de JDBC-methode setObject(integer, Object)
aanroepen om de tekenreeks op te slaan zonder dat er een bepaald gegevenstype is opgegeven. Het JDBC-stuurprogramma verzendt de tekenreeksrepresentatie en de database leidt het type af van het doelkolomtype of het functieargumenttype.
Zie ook
Vragen:
- PostgreSQL JSON-kolom toewijzen aan waardetype Slaapstand
- Zijn JPA (EclipseLink) aangepaste typen mogelijk?
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