繁体   English   中英

将Java Double Infinity和NaN值存储到MS SQL 2008数据库

[英]Storing Java Double Infinity and NaN values to MS SQL 2008 database

在我们的业务逻辑中,我们必须处理正负Double.Infinity值以及Double.NaN值。

我们必须将这些值存储到Microsot SQL Server 2008数据库中。 问题是Microsot SQL Server不支持infinity或nan值。 SQL Server 2005的问题描述 ,也适用于MS SQL Server 2008)。

我们使用Hibernate 3.6.7作为我们的JPA实现和Microsoft的sqljdbc4驱动程序版本4.0.2206.100。

我们试图通过将JPA实体的列定义设置为VARCHAR来解决此问题

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

即使列定义在数据库中正确更改为VARCHAR,这似乎也没有任何影响。 看起来无限值是在JDBC驱动程序的验证中捕获的,因为我们在尝试INSERT Double.Infinity值时得到以下stacktrace:

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

如何解决这个问题的任何想法都是受欢迎的。

以下是此问题的简单解决方法:对字段类型使用String ,并在getter和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;
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM