2012-05-08 17 views
7

ビジネスロジックでは、Double.Infinityの値とDouble.NaNの値を処理する必要があります。Java Double InfinityとNaN値をMS SQL 2008データベースに格納

これらの値をMicrosot SQL Server 2008データベースに格納する必要があります。問題は、Microsot SQL Serverが無限またはナノ値をサポートしていないことです。 (Problem description for SQL Server 2005、MS SQL Server 2008にも適用されます)。

私たちはJPA実装としてHibernate 3.6.7を、Microsoftのsqljdbc4ドライババージョン4.0.2206.100を使用しています。私たちは、この

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

ようVARCHARにJPAエンティティの列定義を設定することで、この問題を解決することを試みた

これは、列の定義が正しくデータベースにVARCHARに変更されていても、何の影響も与えていないようです。

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 

この問題を回避するにはどのように任意のアイデアは歓迎されている:Double.Infinity値を挿入しようとしたとき、我々は、以下のスタックトレースを取得するため、無限大の値はJDBCドライバの検証に巻き込まれているようです。

答えて

1

この問題の簡単な回避策は次のとおりです。 フィールドタイプにStringを使用し、gettersおよびsetterで変換を行います。 この方法では、ビジネスロジックを変更する必要はなく、実際の変換ロジックはうまくカプセル化されています。

// 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

これは問題の回避策のようです。データベースの値がVARCHARであるため、SQLの値に対して計算を実行できない場合があります。 – Spaideri

関連する問題