在我们的业务逻辑中,我们必须处理正负Double.Infinity值以及Double.NaN值。
我们必须将这些值存储到Microsot SQL Server 2008数据库中。问题是Microsot SQL Server不支持无穷大或NaN值。(Problem description for SQL Server 2005,也适用于MS SQL Server2008)。
我们使用Hibernate 3.6.7作为我们的JPA实现和微软的sqljdbc4驱动程序版本4.0.2206.100。
我们尝试通过将JPA实体的列定义设置为VARCHAR来解决此问题,如下所示
@Column(columnDefinition = "VARCHAR(40)")
private Double foo;即使在数据库中将列定义正确地更改为VARCHAR,这似乎也没有任何效果。似乎在JDBC驱动程序的验证中捕获了无穷大的值,因为我们在尝试插入Double.Infinity值时得到了以下堆栈跟踪:
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欢迎任何关于如何解决这个问题的想法。
发布于 2012-05-09 16:53:59
这里有一个解决这个问题的简单方法:将String用于字段类型,并在getters和setters中进行转换。这样,您不必更改您的业务逻辑,并且实际的转换逻辑被很好地封装。
// 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;
}https://stackoverflow.com/questions/10494146
复制相似问题