なぜそれが起こるのか
問題は、PostgreSQLがテキストデータ型と非テキストデータ型の間のキャストについて過度に厳密であるということです。暗黙のキャスト(CASTのないキャスト)は許可されません または:: SQLの場合)textのようなテキストタイプから またはvarchar (character varying )jsonのようなテキストのような非テキストタイプに 、xml 、など。
PgJDBCドライバーは、varcharのデータ型を指定します setStringを呼び出すとき パラメータを割り当てます。列のデータベースタイプ、関数の引数などが実際にはvarcharではない場合 またはtext 、しかし代わりに別のタイプでは、タイプエラーが発生します。これは、他の多くのドライバーやORMにも当てはまります。
PgJDBC:stringtype=unspecified
PgJDBCを使用する場合の最良のオプションは、通常、パラメーターstringtype=unspecifiedを渡すことです。 。これは、setStringを渡すデフォルトの動作をオーバーライドします varcharとしての値 代わりに、データ型を「推測」するのはデータベースに任せます。ほとんどすべての場合、これは希望どおりに機能し、保存するタイプの入力バリデーターに文字列を渡します。
すべて:CREATE CAST ... WITH FUNCTION ...
代わりにCREATE CASTを使用できます データ型固有のキャストを定義して、タイプごとにこれを許可しますが、これは他の場所で副作用を引き起こす可能性があります。これを行う場合は、しないを行ってください WITHOUT FUNCTIONを使用する キャストすると、型の検証がバイパスされ、エラーが発生します。データ型には入力/検証機能を使用する必要があります。 CREATE CASTを使用する 文字列/テキストパラメータのタイプを指定するドライバを停止する方法がない他のデータベースドライバのユーザーに適しています。
例:
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;
すべて:カスタムタイプハンドラー
ORMで許可されている場合は、データ型とその特定のORMのカスタム型ハンドラーを実装できます。これは、Stringを使用するのではなく、PostgreSQLタイプに適切にマッピングされるネイティブJavaタイプを使用している場合に最も役立ちます。 、ただし、ORMでアノテーションなどを使用してタイプハンドラーを指定できる場合にも機能します。
カスタムタイプハンドラーを実装するためのメソッドは、ドライバー、言語、およびORMに固有です。 jsonのJavaとHibernateの例を次に示します。 。
PgJDBC:PGObjectを使用したタイプハンドラー
JavaでネイティブJavaタイプを使用している場合は、PGObjectを拡張できます。 タイプにPgJDBCタイプマッピングを提供します。 PGObjectを使用するには、ORM固有のタイプハンドラーも実装する必要があります。 、ほとんどのORMはtoStringを呼び出すだけなので 彼らが認識しないタイプについて。これは、JavaとPostgreSQLの間で複雑なタイプをマッピングするための推奨される方法ですが、最も複雑な方法でもあります。
PgJDBC:setObject(int, Object)を使用したタイプハンドラー
Stringを使用している場合 より具体的なタイプではなく、Javaで値を保持するために、JDBCメソッドsetObject(integer, Object)を呼び出すことができます。 特定のデータ型が指定されていない文字列を格納します。 JDBCドライバーは文字列表現を送信し、データベースは宛先列タイプまたは関数引数タイプからタイプを推測します。
関連項目
質問:
- postgreSQLJSON列をHibernate値型にマッピングする
- JPA(EclipseLink)カスタムタイプは可能ですか?
外部:
- https://www.postgresql.org/message-id/example@sqldat.com
- https://github.com/pgjdbc/pgjdbc/issues/265
- https://www.pateldenish.com/2013/05/inserting-json-data-into-postgres-using-jdbc-driver.html