Mengapa itu terjadi
Masalahnya adalah PostgreSQL terlalu ketat tentang gips antara tipe data teks dan non-teks. Itu tidak akan mengizinkan pemeran implisit (yang tanpa CAST
atau ::
dalam SQL) dari jenis teks seperti text
atau varchar
(character varying
) ke jenis non-teks seperti teks seperti json
, xml
, dll.
Driver PgJDBC menentukan tipe data varchar
saat Anda memanggil setString
untuk menetapkan parameter. Jika tipe database kolom, argumen fungsi, dll, sebenarnya bukan varchar
atau text
, tetapi sebagai gantinya tipe lain, Anda mendapatkan kesalahan tipe. Hal ini juga berlaku untuk banyak driver dan ORM lainnya.
PgJDBC:stringtype=unspecified
Opsi terbaik saat menggunakan PgJDBC umumnya adalah dengan melewatkan parameter stringtype=unspecified
. Ini menimpa perilaku default melewati setString
nilai sebagai varchar
dan sebagai gantinya menyerahkannya ke database untuk "menebak" tipe data mereka. Dalam hampir semua kasus, ini melakukan persis seperti yang Anda inginkan, meneruskan string ke validator input untuk jenis yang ingin Anda simpan.
Semua:CREATE CAST ... WITH FUNCTION ...
Sebagai gantinya, Anda dapat CREATE CAST
untuk mendefinisikan pemeran khusus tipe data untuk mengizinkan ini berdasarkan tipe demi tipe, tetapi ini dapat memiliki efek samping di tempat lain. Jika Anda melakukan ini, jangan gunakan WITHOUT FUNCTION
gips, mereka akan melewati validasi tipe dan menghasilkan kesalahan. Anda harus menggunakan fungsi input/validasi untuk tipe data. Menggunakan CREATE CAST
cocok untuk pengguna driver database lain yang tidak memiliki cara untuk menghentikan driver yang menentukan jenis parameter string/teks.
misalnya
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;
Semua:Pengendali tipe khusus
Jika ORM Anda mengizinkan, Anda dapat menerapkan penangan tipe kustom untuk tipe data dan ORM spesifik tersebut. Ini sangat berguna saat Anda menggunakan tipe Java asli yang memetakan dengan baik ke tipe PostgreSQL, daripada menggunakan String
, meskipun itu juga dapat berfungsi jika ORM Anda memungkinkan Anda menentukan penangan tipe menggunakan anotasi, dll.
Metode untuk mengimplementasikan penangan tipe khusus adalah khusus untuk driver, bahasa, dan ORM. Berikut adalah contoh untuk Java dan Hibernate untuk json
.
PgJDBC:ketik handler menggunakan PGObject
Jika Anda menggunakan tipe Java asli di Java, Anda dapat memperluas PGObject
untuk menyediakan pemetaan tipe PgJDBC untuk tipe Anda. Anda mungkin juga perlu menerapkan penangan tipe khusus ORM untuk menggunakan PGObject
Anda , karena sebagian besar ORM hanya akan memanggil toString
pada jenis yang tidak mereka kenali. Ini adalah cara yang lebih disukai untuk memetakan tipe kompleks antara Java dan PostgreSQL, tetapi juga yang paling kompleks.
PgJDBC:Ketik handler menggunakan setObject(int, Object)
Jika Anda menggunakan String
untuk menyimpan nilai di Java, daripada tipe yang lebih spesifik, Anda dapat memanggil metode JDBC setObject(integer, Object)
untuk menyimpan string tanpa tipe data tertentu yang ditentukan. Driver JDBC akan mengirimkan representasi string, dan database akan menyimpulkan tipe dari tipe kolom tujuan atau tipe argumen fungsi.
Lihat juga
Pertanyaan:
- Memetakan kolom JSON postgreSQL ke tipe nilai Hibernate
- Apakah tipe kustom JPA (EclipseLink) memungkinkan?
Eksternal:
- 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