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

发布于 2024-11-03 12:42:05 字数 534 浏览 0 评论 0原文

我有以下简单的 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)?理想情况下,我想像往常一样通过实体管理器来完成此操作。

提前致谢。

I have the following simple JPA entity:

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

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

a and b may be set to Double.POSITIVE_INFINITY. When I try to store entity with double set to +INF into database (MySQL) using standard entity manager I get exception:

java.sql.SQLException: 'Infinity' is not a valid numeric or approximate numeric value

As far as I know MySQL may not support NaN/-INF/+INF numbers. Is there any way to store this entity without writing HQL queries and translating +INF into null (or max double) ? Ideally, I'd like to do it via entity manager as usual.

Thanks in advance.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

哀由 2024-11-10 12:42:05

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

 //--

 @PrePersist  
 @PreUpdate  
 private void resetField() {

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

 //--

Entity life-cycle callback methods @PrePersist, @PreUpdate can be used here to verify the field value NAN/-INF/+INF etc & then setting the default value accordingly.

 //--

 @PrePersist  
 @PreUpdate  
 private void resetField() {

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

 //--
北方的巷 2024-11-10 12:42:05

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

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

积极的情况也是如此。 其他资源也使用1e500

我建议您不要使用无穷大,而是使用 Float.MAX_VALUEFloat.MIN_VALUE (或 Double 等效项)

如果您不能这样做在您的代码中设置值时,请按照已经建议的那样在 @PrePersist 中执行此操作。

MySQL doesn't seem to support "infinity". This article writes that:

Storing and retrieving negative infinity in a MySQL database is accomplished by inserting an arbitrarily large negative number.

Same goes for positive. Other resources also use 1e500.

Instead of using infinity, I would suggest that you use Float.MAX_VALUE and Float.MIN_VALUE (or Double equivalents)

If you can't do this in your code when setting the values, do it in a @PrePersist as already suggested.

夏の忆 2024-11-10 12:42:05

我通过添加一个 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        |

I managed this problem by adding a varchar column to store the text representation of Float.NaN, Float.POSITIVE_INFINITY and Float.NEGATIVE_INFINITY while the original column will store NULL.
Then I use the setter and the getter to do manage those two columns.

In my @Entity class

/** 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;
    }
}

Result :

| 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        |
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文