在MySQL中存储Double.POSITIVE_INFINITY(EJB实体/ JBoss)

时间:2011-04-27 16:58:41

标签: mysql jpa jboss ejb infinity

我有以下简单的JPA实体:

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

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

a b 可能会设为Double.POSITIVE_INFINITY。当我尝试使用标准实体管理器将具有双重设置的实体存储到数据库(MySQL)中时,我得到异常:

  

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

据我所知,MySQL可能不支持NaN / -INF / + INF号码。有没有办法存储这个实体而不编写HQL查询并将+ INF转换为null(或max double)?理想情况下,我希望像往常一样通过实体经理来做。

提前致谢。

3 个答案:

答案 0 :(得分:3)

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

 //--

 @PrePersist  
 @PreUpdate  
 private void resetField() {

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

 //--

答案 1 :(得分:3)

MySQL似乎不支持“无限”。 This article写道:

  

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

同样积极的。 Other resources也使用1e500

我建议您使用Float.MAX_VALUEFloat.MIN_VALUE(或等同于Double

,而不是使用无穷大。

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

答案 2 :(得分: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        |