Lỗi Xóa Sô 0 Khi Đọc BigDecimal Bằng PostgreSQL JDBC Driver 42.3.0 - Loc88 Club Game Bài Tặng Code

| Apr 2, 2025 min read

Ngày 17 tháng 11 năm 2023 - Công nghệ thông tin

Trong quá trình sử dụng cách tiếp cận nguyên bản của Java để truy cập cơ sở dữ liệu PostgreSQL, tôi tình cờ phát hiện ra một lỗi nghiêm trọng liên quan đến việc đọc kiểu BigDecimal bằng PostgreSQL JDBC Driver phiên bản 42.3.0. Cụ thể, khi đọc giá trị từ cột có kiểu numeric, các số không (0) ở phía trước dấu thập phân bị xóa hoàn toàn. Tôi ghi lại sự cố này để chia sẻ với cộng đồng.

Lỗi được gây ra bởi PostgreSQL JDBC Driver phiên bản 42.3.0, và Maven dependency của nó như 22win casino sau:

<dependency>
  <groupId>org.postgresql</groupId>
  <artifactId>postgresql</artifactId>
  <version>42.3.0</version>
</dependency>

Bên cạnh đó, dưới đây là các phiên bản phần mềm khác mà tôi đã sử dụng khi phát hiện ra lỗi này:

JDK: Amazon Corretto 17.0.8
Maven: 3.9.2
PostgreSQL Server: 16.0

game nhà cái tặng tiền cược miễn phí 1. Mô tả vấn đề

Khi sử dụng PostgreSQL JDBC Driver 42.3.0 để đọc giá trị từ cột có kiểu numeric thành đối tượng BigDecimal trong Java, một lỗi nghiêm trọng xảy ra: tất cả các số không (0) ở phía trước dấu thập phân bị xóa mất. Ví dụ, nếu giá trị ban đầu là 20000.00000000 (kiểu numeric(20,8)), thì sau khi đọc nó sẽ trở thành 2.00000000. Điều này thay đổi hoàn toàn giá trị gốc và tạo ra một lỗi rất nghiêm trọng.

Ban đầu, khi phát hiện ra vấn đề này, tôi cảm thấy khá ngạc nhiên và không chắc chắn liệu lỗi có thực sự xuất phát từ JDBC Driver hay không. Sau khi tìm kiếm trên GitHub, tôi đã tìm thấy một số Issue tương tự, xác nhận rằng đây là một vấn đề tồn tại trong phiên bản 42.3.0 của PostgreSQL JDBC Driver. Để minh họa rõ ràng hơn, tôi đã chuẩn bị một kịch bản database và chương trình ví dụ bằng Java để tái hiện lỗi này.

2. Tái hiện vấn đề

2.1 Script Database

Trên máy chủ PostgreSQL cục bộ, tôi đã chạy các câu lệnh sau:

-- Tạo bảng mới
CREATE TABLE product (
    id INT PRIMARY KEY,
    price NUMERIC(20,8) NOT NULL
);

-- Chèn giá trị vào bảng
INSERT INTO product VALUES (1, 20000);

2.2 Chương trình tái hiện

Tôi đã viết một chương trình kiểm thử bằng JUnit để tái hiện lỗi:

import org.junit.jupiter.api.Test;
import java.math.BigDecimal;
import java.sql.DriverManager;
import java.sql.SQLException;

import static org.junit.jupiter.api.Assertions.assertEquals;

public class [Loc88 Club Game Bài Tặng Code](/post/search-in-rotated-sorted-array-ii/)  BigDecimalTest {

    @Test
    public void test() throws SQLException {
        try (var conn = DriverManager.getConnection("jdbc:postgresql://localhost:5432/test", "postgres", "postgres")) {
            var sql = "SELECT price FROM product WHERE id=1";
            try (var stmt = conn.prepareStatement(sql)) {
                var priceInserted = new BigDecimal("20000.00000000");
                for (int round = 0; round < 10; round++) {
                    try (var rs = stmt.executeQuery()) {
                        while (rs.next()) {
                            var price = rs.getBigDecimal("price");
                            assertEquals(priceInserted, price, "Kiểm tra thất bại ở vòng lặp " + round);
                        }
                    }
                }
            }
        }
    }
}

Chương trình trên sử dụng phương pháp DriverManager.getConnection() để thiết lập kết nối với cơ sở dữ liệu PostgreSQL. Sau đó, nó sử dụng conn.prepareStatement() để chuẩn bị câu truy vấn SQL và stmt.executeQuery() để thực thi truy vấn 10 lần. Trong mỗi lần lặp, chương trình sử dụng rs.getBigDecimal("price") để lấy giá trị của cột price và so sánh với giá trị kỳ vọng.

Kết quả cho thấy rằng, trong 5 lần đầu tiên, mọi thứ hoạt động bình thường. Tuy nhiên, bắt đầu từ lần lặp thứ 6, giá trị 20000.00000000 bị đọc sai thành 2.00000000.

org.opentest4j.AssertionFailedError: Kiểm tra thất bại ở vòng lặp 5 ==>
Giá trị mong đợi :20000.00000000
Giá trị thực tế   :2.00000000

3. Giải pháp

Để khắc phục lỗi này, bạn chỉ cần nâng cấp PostgreSQL JDBC Driver lên phiên bản 42.3.1 hoặc cao hơn. Dependency Maven mới sẽ như sau:

<dependency>
  <groupId>org.postgresql</groupId>
  <artifactId>postgresql</artifactId>
  <version>42.3.1</version>
</dependency>

Như vậy, bài viết này đã phát hiện và mô tả chi tiết về lỗi liên quan đến việc đọc giá trị BigDecimal trong PostgreSQL JDBC Driver 42.3.0. Đồng thời, chúng ta cũng đã tìm ra giải pháp phù hợp để xử lý vấn đề này.

Mã nguồn tái hiện đã được đăng tải lên GitHub cá nhân của tôi.