Хранение Double.POSITIVE_INFINITY в MySQL (объект EJB / JBoss) - PullRequest
6 голосов
/ 27 апреля 2011

У меня есть следующая простая сущность JPA:

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

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

a и b могут быть установлены на Double.POSITIVE_INFINITY. Когда я пытаюсь сохранить сущность с двойным значением + INF в базе данных (MySQL), используя стандартный менеджер сущностей, я получаю исключение:

java.sql.SQLException: 'Infinity' не является допустимым числовым или приблизительным числовым значением

Насколько я знаю, MySQL может не поддерживать номера NaN / -INF / + INF. Есть ли способ сохранить эту сущность без написания HQL-запросов и перевода + INF в ноль (или max double)? В идеале я хотел бы сделать это через менеджера сущностей, как обычно.

Заранее спасибо.

Ответы [ 3 ]

3 голосов
/ 27 апреля 2011

MySQL не поддерживает бесконечность. В этой статье написано, что:

Сохранение и извлечение отрицательной бесконечности в базе данных MySQL выполняется путем вставки произвольно большого отрицательного числа.для позитива. Другие ресурсы также используют 1e500.

Вместо бесконечности я бы предложил использовать Float.MAX_VALUE и Float.MIN_VALUE (или Double эквиваленты)

Если вы не можете сделать это в своем коде при установке значений, сделайте это в @PrePersist, как уже предлагалось.

3 голосов
/ 27 апреля 2011

Методы обратного вызова жизненного цикла объекта @PrePersist, @PreUpdate могут использоваться здесь для проверки значения поля NAN / -INF / + INF и т. Д., А затем для установки значения по умолчанию соответствующим образом.

 //--

 @PrePersist  
 @PreUpdate  
 private void resetField() {

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

 //--
0 голосов
/ 25 июля 2016

Я решил эту проблему, добавив столбец varchar для хранения текстового представления Float.NaN, Float.POSITIVE_INFINITY и Float.NEGATIVE_INFINITY, в то время как исходный столбец будет хранить NULL. Затем я использую установщик и получатель для управления этими двумя столбцами.

В моем классе @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        |
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...