Ответ 1
Почему это происходит
Проблема заключается в том, что 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. Это в основном полезно, когда вы используете собственный тип Java, который хорошо отображает тип PostgreSQL, вместо использования String
, хотя он также может работать, если ваш ORM позволяет вам указывать обработчики типов с помощью аннотаций и т.д.
Способы реализации обработчиков настраиваемых типов зависят от типа драйвера, языка и ORM. Вот пример для Java и Hibernate для json
.
PgJDBC: обработчик типа PGObject
Если вы используете родной Java-тип в Java, вы можете расширить PGObject
, чтобы обеспечить сопоставление типов PgJDBC для вашего типа. Возможно, вам также понадобится реализовать обработчик типа ORM, чтобы использовать ваш PGObject
, поскольку большинство ORM просто вызовет toString
по типам, которые они не распознают. Это предпочтительный способ сопоставления сложных типов между Java и PostgreSQL, но также и самого сложного.
PgJDBC: обработчик типа setObject(int, Object)
Если вы используете String
для хранения значения в Java, а не для более конкретного типа, вы можете вызвать метод JDBC setObject(integer, Object)
для хранения строки без определенного типа данных. Драйвер JDBC отправит строковое представление, и база данных выведет тип из типа столбца назначения или типа аргумента функции.
См. также
Вопросы:
- Отображение столбца JSON postgreSQL для типа значения Hibernate
- Возможны ли пользовательские типы JPA (EclipseLink)?
Внешний: