Pertanyaan Mengubah perilaku java.sql.Date setelah peningkatan klien OJBC


Setelah upgrade dari klien OJDBC dari versi 11.2.0 ke 12.1.0, saya mengalami perilaku yang berbeda dalam mengikat objek java.sql.Date ke PreparedStatement.

Dalam pernyataan yang disiapkan, variabel host "f.plan_date =?" harus diikat dengan nilai objek java.util.Date, menjadi masukan yang diperoleh di tempat lain dalam kode. Tipe data kolom dalam tabel Oracle adalah "DATE" dan hanya bagian tanggal yang harus diperhitungkan - waktu tidak relevan.

Saya menerjemahkan objek java.util.Date dalam objek java.sql.Date dengan cara berikut: statementRegisterJobs.setDate(3, new java.sql.Date(planDate.getTime())); 

Ini bekerja dengan baik dengan klien 11.2.0. Namun, hal-hal cenderung salah setelah peningkatan menuju 12.1.0. Tidak ada catatan yang diambil lagi. Setelah berjam-jam melakukan debugging, saya menemukan bahwa masalah terkait dengan variabel tanggal. Cara kerja berikut memberi saya catatan saya kembali: statementRegisterJobs.setDate(3, java.sql.Date.valueOf("2014-08-21")); 

Bisakah seseorang mengklarifikasi perilaku ini? Objek java.util.Date akhirnya dapat memiliki komponen waktu, dan saya memiliki perasaan tidak terdefinisi bahwa ini bisa berhubungan dengan masalah entah bagaimana. Di sisi lain, item berikut harus menyatakan bahwa komponen waktu diabaikan dalam java.sql.Date, tidak peduli bagaimana objek itu dibangun ...

  • Di Java 6 API untuk java.sql.Date, saya menemukan pernyataan berikut: "Metode ini tidak lagi digunakan dan tidak boleh digunakan karena nilai-nilai Tanggal SQL tidak memiliki komponen waktu." (metode 'getHours ()'). Jadi ini akan berarti bahwa aspek waktu diabaikan ketika mengkonversi java.util.Date menjadi java.sql.Date.
  • Hal ini dikonfirmasi oleh informasi dalam dokumentasi konstruktor: "Membangun objek Tanggal menggunakan nilai waktu milidetik yang diberikan. Jika nilai milidetik yang diberikan berisi informasi waktu, pengemudi akan mengatur komponen waktu ke waktu di zona waktu default (waktu zona mesin virtual Java menjalankan aplikasi) yang sesuai dengan nol GMT. "
  • Selain itu, saya tidak bisa mendapatkan aspek waktu yang mungkin keluar dari objek java.sql.Date: toString () memberi saya hanya tanggal, getHours () melempar pengecualian.
  • Dan bagaimana ini bisa terkait dengan pembaruan di klien JDBC?

Setiap pemikiran dihargai :) Terima kasih banyak sebelumnya.


8
2017-08-22 15:21


asal


Jawaban:


Bertentangan dengan apa yang dinyatakan API Java, saat membuat objek java.sql.Date dengan melewatkan milidetik waktu nilai aspek waktu tampaknya disimpan dalam objek dan tidak gagal ke nol saat menggunakan driver OJDBC 12.1.0.

Ini adalah tes yang saya buat:

java.util.Date utilDate = new Date();
java.sql.Date sqlDate1 = new java.sql.Date(utilDate.getTime());
java.sql.Date sqlDate2 = java.sql.Date.valueOf("2014-08-27");

Saya menyiapkan pernyataan berikut (SELECT to_char(?, 'YYYY-MM-DD HH24:MI:SS') testDate FROM dual), ikatkan baik sqlDate1 dan sqlDate2 dan dapatkan hasil berikut.

  1. Dengan versi driver 11.2.0

    • sqlDate1: 2014-08-27 00:00:00
    • sqlDate2: 2014-08-27 00:00:00
  2. Dengan versi driver 12.1.0

    • sqlDate1: 2014-08-27 14:47:29
    • sqlDate2: 2014-08-27 00:00:00

Ini tidak sejalan dengan dokumentasi di API:

Jika nilai milidetik yang diberikan berisi informasi waktu, pengemudi   akan mengatur komponen waktu ke waktu di zona waktu default (   zona waktu mesin virtual Java menjalankan aplikasi) bahwa   sesuai dengan nol GMT.

Namun, mengetahui ini saya dapat memperbaiki masalah dengan memaksa informasi waktu dari objek tanggal sql menjadi tengah malam.


6
2017-08-27 15:23