2011-11-21 27 views
9

Nếu entity.getHistory() là đoạn rỗng mã sau:PostgreSQL JDBC Null Chuỗi thực hiện như là một bytea

(getEntityManager() trả về mùa xuân tiêm EntityManager, cơ sở dữ liệu loại lịch sử lĩnh vực là: văn bản hoặc varchar2 (2000)

Query query = getEntityManager().createNativeQuery("insert into table_name(..., history, ....) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)") 
[...] 
.setParameter(6, entity.getHistory()) 
[...] 

query.executeUpdate(); 

Cung cấp ngoại lệ lạ:

17/11/11 06:26:09:009 [pool-2-thread-1] WARN util.JDBCExceptionReporter:100 - SQL Error: 0, SQLState: 42804 
17/11/11 06:26:09:009 [pool-2-thread-1] ERROR util.JDBCExceptionReporter:101 - ERROR: **column "history" is of type text but expression is of type bytea** 

Gợi ý: Bạn sẽ cần phải viết lại hoặc đúc biểu thức

01.235.

Vấn đề chỉ xảy ra trong cấu hình này:
Hệ điều hành: CentOS phát hành 5.6 (Final)
Java: 1.6.0_26
DB: PostgreSQL 8.1
JDBC driver: postgresql-9.1-901.jdbc4
Application Server: apache -tomcat-6.0.28

Mọi thứ hoạt động tốt trên vài cấu hình khác hoặc khi lịch sử là chuỗi rỗng. Tuyên bố tương tự được thực hiện từ pgAdmin hoạt động tốt.

Tôi đoán vấn đề nằm trong trình điều khiển JDBC PostgreSQL, có một số lý do hợp lý để xử lý chuỗi rỗng dưới dạng giá trị bytea không? Có lẽ một số thay đổi kỳ lạ giữa Postgres 8 và 9?

+0

Tôi nghi ngờ EntityManager gọi phương thức 'PreparedStatement.setXXX()' sai cho giá trị NULL. Bạn cũng có thể thử trình điều khiển JDBC 8.1. Btw: bạn có biết rằng 8.1 không còn được hỗ trợ? –

+0

Bạn có thể làm rõ hai đoạn đầu tiên của mình không? Họ dường như không có ý nghĩa. –

+0

Cùng một mã làm việc tốt với PostgreSQL 9+ (@a_horse_with_no_name Khách hàng phải có 8.1 ...), Windows 7 vv.Nếu entity.getHistory() là "" thay vì null nó hoạt động. Cùng một chèn được thực hiện từ pgAdmin hoạt động tốt. – laidlook

Trả lời

1

Nếu bạn sẵn sàng để sử dụng lớp PreparedStatement thay vì truy vấn:

if (entity.getHistory() == null) 
    stmt.setNull(6, Types.VARCHAR); 
else 
    stmt.setString(6, entity.getHistory()); 

(Có thể là sử dụng ?::text trong chuỗi truy vấn của bạn cũng sẽ làm việc, nhưng tôi chưa bao giờ làm nó theo cách mà bản thân mình.)

4

Vì bạn đang gọi setParameter(int,Object) với giá trị null, khi đoán người quản lý thực thể không biết loại kiên trì nào sẽ sử dụng để ràng buộc tham số. Istr Hibernate có một predilection để sử dụng SerializableType, mà sẽ tương đương với một bytea.

Bạn có thể sử dụng phương thức setParameter thay cho đối tượng Tham số để bạn có thể chỉ định loại không? Tôi đã không thực sự sử dụng JPA, do đó, không thể cung cấp cho một con trỏ chi tiết.

(IMHO này là bạn chỉ món tráng miệng cho lạm dụng giao diện truy vấn nguồn gốc-sql EntityManager để làm chèn, chứ không phải là thực sự lập bản đồ thực thể, hoặc chỉ thả qua để JDBC)

4

Có một sửa chữa đơn giản: khi bạn đang xây dựng chuỗi truy vấn, nếu tham số sẽ là null - hãy sử dụng "null" thay vì "?".

Như @araqnid cho biết, Hibernate không chính xác đúc các giá trị null vào loại bytea bởi vì nó không biết gì tốt hơn.

0

Tập JDBCNói với tham số kiểu sql là dự phòng cho các trình điều khiển JDBC kế thừa không vượt qua JDBC Driver Test Suite.

Người ta có thể bảo vệ chống lại các lỗi rỗng trong các truy vấn như sau:

SELECT a TỪ Tác giả một ĐỊA ĐIỂM: lastName IS NULL OR LOWER (a.lastName) =: lastName

này nên làm việc trong PostgreSQL sau bản sửa lỗi này issue.

0

Sử dụng Hibernate phiên cụ API hoạt động như một cách giải quyết:

String sql = "INSERT INTO person (id, name) VALUES (:id, :name)"; 
Session session = em.unwrap(Session.class); 
SQLQuery insert = session.createSQLQuery(sql); 
sql.setInteger("id", 123); 
sql.setString("name", null); 
insert.executeUpdate(); 

Tôi cũng đã nộp HHH-9165 để báo cáo vấn đề này, nếu nó thực sự là một lỗi.

+0

lưu ý Tôi đã có vấn đề này với một 'Short' và ở đó bạn không thể sử dụng' setShort() 'bởi vì nó có một non-nullable' short'. Với hibernate 4.x, giải pháp là: '.setParameter (" short ", ShortValue, ShortType.INSTANCE);' (với 3.x Tôi nghĩ nó là 'Hibernate.SHORT' thay vì dùng' ShortType'). –

Các vấn đề liên quan