2012-05-08 31 views
7

Trong logic nghiệp vụ của chúng ta, chúng ta phải xử lý các giá trị dương và âm Double.Infinity cũng như các giá trị Double.NaN.Lưu trữ các giá trị Java Double Infinity và NaN vào cơ sở dữ liệu MS SQL 2008

Chúng tôi phải lưu trữ các giá trị này vào cơ sở dữ liệu Microsot SQL Server 2008. Vấn đề là Microsot SQL Server không hỗ trợ các giá trị vô cùng hoặc nan. (Problem description for SQL Server 2005, cũng áp dụng cho MS SQL Server 2008).

Chúng tôi đang sử dụng Hibernate 3.6.7 làm triển khai JPA và phiên bản trình điều khiển sqljdbc4 của Microsoft 4.0.2206.100.

Chúng tôi đã cố gắng để giải quyết vấn đề này bằng cách thiết lập định nghĩa cột JPA thực thể để VARCHAR như thế này

@Column(columnDefinition = "VARCHAR(40)") 
private Double foo; 

này dường như không có bất kỳ tác dụng, mặc dù định nghĩa cột được thay đổi đúng cách để VARCHAR trong cơ sở dữ liệu. Dường như giá trị vô cùng bị bắt trong xác nhận JDBC lái xe vì chúng ta có được stacktrace sau khi cố gắng INSERT Double.Infinity giá trị:

Caused by: com.microsoft.sqlserver.jdbc.SQLServerException: The incoming tabular data stream (TDS) remote procedure call (RPC) protocol stream is incorrect. Parameter 6 (""): The supplied value is not a valid instance of data type float. Check the source data for invalid values. An example of an invalid value is data of numeric type with scale greater than precision. 
    at com.microsoft.sqlserver.jdbc.SQLServerException.makeFromDatabaseError(SQLServerException.java:216) 
    at com.microsoft.sqlserver.jdbc.SQLServerStatement.getNextResult(SQLServerStatement.java:1515) 
    at com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement.doExecutePreparedStatement(SQLServerPreparedStatement.java:404) 
    at com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement$PrepStmtExecCmd.doExecute(SQLServerPreparedStatement.java:350) 
    at com.microsoft.sqlserver.jdbc.TDSCommand.execute(IOBuffer.java:5696) 
    at com.microsoft.sqlserver.jdbc.SQLServerConnection.executeCommand(SQLServerConnection.java:1715) 
    at com.microsoft.sqlserver.jdbc.SQLServerStatement.executeCommand(SQLServerStatement.java:180) 
    at com.microsoft.sqlserver.jdbc.SQLServerStatement.executeStatement(SQLServerStatement.java:155) 
    at com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement.executeUpdate(SQLServerPreparedStatement.java:314) 
    at org.apache.commons.dbcp.DelegatingPreparedStatement.executeUpdate(DelegatingPreparedStatement.java:105) 
    at org.apache.commons.dbcp.DelegatingPreparedStatement.executeUpdate(DelegatingPreparedStatement.java:105) 
    at org.hibernate.id.IdentityGenerator$GetGeneratedKeysDelegate.executeAndExtract(IdentityGenerator.java:94) 
    at org.hibernate.id.insert.AbstractReturningDelegate.performInsert(AbstractReturningDelegate.java:57) 
    ... 79 more 

Bất kỳ ý tưởng làm thế nào để làm việc xung quanh vấn đề này đều được chào đón.

Trả lời

1

Đây là giải pháp đơn giản cho vấn đề này: Sử dụng String cho loại trường và thực hiện chuyển đổi trong getters và setters. Bằng cách này bạn không phải thay đổi logic kinh doanh của bạn và logic chuyển đổi thực tế được đóng gói độc đáo.

// Column definition is not a necessity here 
@Column(columnDefinition = "VARCHAR(40)") 
private String foo; 

public Double getFoo() { 
    return this.foo != null ? Double.valueOf(this.foo) : null; 
} 

public void setFoo(Double d) { 
    this.foo = d != null ? d.toString() : null; 
} 
+1

Điều này có vẻ như giải pháp thay thế cho sự cố. Chỉ có giới hạn là vì giá trị là VARCHAR trong cơ sở dữ liệu, bạn có thể không thực hiện được các phép tính cho các giá trị trong SQL. – Spaideri

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