6

我有以下简单的 JPA 实体:

@Entity
@Table( name = myentity_table )
public class MyEntity {

  private double a;
  private double b;
  //(...)
}

ab可以设置为Double.POSITIVE_INFINITY。当我尝试使用标准实体管理器将具有双重设置为 +INF 的实体存储到数据库(MySQL)中时,出现异常:

java.sql.SQLException:'Infinity' 不是有效的数值或近似数值

据我所知 MySQL 可能不支持 NaN/-INF/+INF 数字。有没有办法在不编写 HQL 查询并将 +INF 转换为 null(或 max double)的情况下存储此实体?理想情况下,我想像往常一样通过实体管理器来做。

提前致谢。

4

3 回答 3

3

实体生命周期回调方法@PrePersist、@PreUpdate 可用于验证字段值 NAN/-INF/+INF 等,然后相应地设置默认值。

 //--

 @PrePersist  
 @PreUpdate  
 private void resetField() {

      if(field == Double.POSITIVE_INFINITY)
            field = somePredefinedValue;
 }

 //--
于 2011-04-27T17:44:37.583 回答
3

MySQL 似乎不支持“无穷大”。这篇文章写道:

在 MySQL 数据库中存储和检索负无穷大是通过插入一个任意大的负数来完成的。

积极的也一样。其他资源也使用1e500.

我建议您使用Float.MAX_VALUEFloat.MIN_VALUE(或Double等价物)而不是使用无穷大

如果您在设置值时无法在代码中执行此操作,请@PrePersist按照已建议的方式执行此操作。

于 2011-04-27T18:02:17.493 回答
0

我通过添加一个 varchar 列来存储 的文本表示来解决这个问题Float.NaNFloat.POSITIVE_INFINITYFloat.NEGATIVE_INFINITY原始列将存储NULL. 然后我使用 setter 和 getter 来管理这两列。

在我的@Entity 课程中

/** The value I persist. See it is a Float; */
@Column(name = "VALUE")
private Float value;

/** the 'value complement' that does the trick. */
@Column(name = "VALUE_COMPLEMENT") // You can see I've added a new column in my table (it is a varchar)
private String valueComplement;

/**
 * value getter.
 * If my value is null, it could mean that it is a NaN or +/- infinity.
 * Then let's check the complement.
 */
public Float getValue() {
    if (value == null) {
        try {
            return Float.parseFloat(this.valueComplement);
        } catch (NumberFormatException e) {
            return null;
        }
    } else {
        return value;
    }
}

/**
 * value setter
 * If the given value is a NaN or Inf, set this.value to null 
 * and this.complement to the string representation of NaN or +/- Inf.
 */
public void setValue(Float value) {
    if (value != null && (value.isNaN() || value.isInfinite())) {
        this.valueComplement = value.toString();
        this.value = null;
    } else {
        this.value = value;
    }
}

结果 :

| ID | LABEL                 | VALUE | VALUE_COMPLEMENT |
| -- | --------------------- | ----- | ---------------- |
|  1 | PI                    |  3.14 | NULL             |
|  2 | gravity acceleration  |  9.81 | NULL             |
|  3 | sqare root of -1      | NULL  | NaN              |
|  4 | log of 0              | NULL  | -Infinity        |
于 2016-07-25T09:02:47.380 回答