Сохранение Double.POSITIVE_INFINITY в MySQL (объект EJB / JBoss)

#mysql #jpa #jboss #ejb #infinity

#mysql #jpa #jboss #ejb #бесконечность

Вопрос:

У меня есть следующий простой объект 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 в null (или max double)? В идеале я хотел бы сделать это через entity manager, как обычно.

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

Ответ №1:

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

  //--

 @PrePersist  
 @PreUpdate  
 private void resetField() {

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

 //--
  

Комментарии:

1. Спасибо, вот и все! Мое решение состоит в том, чтобы использовать обратные вызовы до / после и (как я выбрал) в случае INF установить для поля значение Double. MAX_VALUE (это для обратных вызовов до *, для post это должно быть сделано MAX-> INF)

Ответ №2:

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

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

То же самое касается positive. Другие ресурсы также используют 1e500 .

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

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

Комментарии:

1. Мне нравится идея преднамеренного использования не бесконечных констант для эффективного представления бесконечности в приложении. @PrePersist Метод может удивить пользователей вашего кода, если они попытаются сохранить бесконечность, но получить что-то еще обратно. Для моего приложения я выбрал 1e12 (1 триллион) в качестве значения, представляющего бесконечность, поскольку у нас нет требования хранить значение выше этого. Мне больше понравилось красивое круглое число, подобное 1 триллиону, чем Float.MAX_VALUE, потому что его намного проще писать в SQL.

Ответ №3:

Я справился с этой проблемой, добавив столбец 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 amp;amp; (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        |