Tại sao nó lại xảy ra
Vấn đề là PostgreSQL quá nghiêm ngặt về các phôi giữa các kiểu dữ liệu văn bản và không phải văn bản. Nó sẽ không cho phép truyền ngầm (một truyền không có CAST
hoặc ::
trong SQL) từ một loại văn bản như text
hoặc varchar
(character varying
) sang loại không phải văn bản giống như văn bản như json
, xml
, v.v.
Trình điều khiển PgJDBC chỉ định kiểu dữ liệu của varchar
khi bạn gọi setString
để gán một tham số. Nếu kiểu cơ sở dữ liệu của cột, đối số hàm, v.v., không thực sự là varchar
hoặc text
, nhưng thay vào đó là một kiểu khác, bạn gặp lỗi kiểu. Điều này cũng đúng với khá nhiều trình điều khiển và ORM khác.
PgJDBC:stringtype=unspecified
Tùy chọn tốt nhất khi sử dụng PgJDBC thường là chuyển tham số stringtype=unspecified
. Điều này ghi đè hành vi mặc định của việc truyền setString
các giá trị dưới dạng varchar
và thay vào đó, để cơ sở dữ liệu "đoán" kiểu dữ liệu của họ. Trong hầu hết các trường hợp, điều này thực hiện chính xác những gì bạn muốn, chuyển chuỗi tới trình xác thực đầu vào cho loại bạn muốn lưu trữ.
Tất cả:CREATE CAST ... WITH FUNCTION ...
Thay vào đó, bạn có thể CREATE CAST
để xác định một kiểu truyền dữ liệu cụ thể để cho phép điều này trên cơ sở từng loại, nhưng điều này có thể có tác dụng phụ ở những nơi khác. Nếu bạn làm điều này, không sử dụng WITHOUT FUNCTION
phôi, chúng sẽ bỏ qua xác thực kiểu và dẫn đến lỗi. Bạn phải sử dụng chức năng nhập / xác nhận cho kiểu dữ liệu. Sử dụng CREATE CAST
phù hợp với người dùng trình điều khiển cơ sở dữ liệu khác không có bất kỳ cách nào để dừng trình điều khiển chỉ định loại cho các tham số chuỗi / văn bản.
ví dụ:
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;
Tất cả:Trình xử lý kiểu tùy chỉnh
Nếu ORM của bạn cho phép, bạn có thể triển khai trình xử lý kiểu tùy chỉnh cho kiểu dữ liệu và ORM cụ thể đó. Điều này chủ yếu hữu ích khi bạn đang sử dụng kiểu Java gốc ánh xạ tốt đến kiểu PostgreSQL, thay vì sử dụng String
, mặc dù nó cũng có thể hoạt động nếu ORM của bạn cho phép bạn chỉ định trình xử lý loại bằng cách sử dụng chú thích, v.v.
Các phương pháp triển khai trình xử lý kiểu tùy chỉnh là trình điều khiển, ngôn ngữ và ORM cụ thể. Đây là một ví dụ cho Java và Hibernate cho json
.
PgJDBC:nhập trình xử lý bằng PGObject
Nếu bạn đang sử dụng kiểu Java gốc trong Java, bạn có thể mở rộng PGObject
để cung cấp ánh xạ loại PgJDBC cho loại của bạn. Bạn có thể cũng sẽ cần triển khai trình xử lý loại ORM cụ thể để sử dụng PGObject
của bạn , vì hầu hết các ORM sẽ chỉ gọi toString
trên các loại mà họ không nhận ra. Đây là cách ưu tiên để ánh xạ các kiểu phức tạp giữa Java và PostgreSQL, nhưng cũng là cách phức tạp nhất.
PgJDBC:Nhập trình xử lý bằng setObject(int, Object)
Nếu bạn đang sử dụng String
để giữ giá trị trong Java, thay vì một kiểu cụ thể hơn, bạn có thể gọi phương thức JDBC setObject(integer, Object)
để lưu trữ chuỗi không có kiểu dữ liệu cụ thể nào được chỉ định. Trình điều khiển JDBC sẽ gửi biểu diễn chuỗi và cơ sở dữ liệu sẽ suy ra kiểu từ kiểu cột đích hoặc kiểu đối số hàm.
Xem thêm
Câu hỏi:
- Ánh xạ cột JSON postgreSQL thành loại giá trị Hibernate
- Có thể sử dụng các loại tùy chỉnh JPA (EclipseLink) không?
Bên ngoài:
- 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