2011-04-27 11 views
6

Tengo el siguiente sencillo entidad JPA:Almacenamiento Double.POSITIVE_INFINITY en MySQL (entidad EJB/JBoss)

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

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

un y b se puede establecer en Double.POSITIVE_INFINITY. Cuando trato de entidad de tienda con doble juego a + INF en base de datos (MySQL) usando el administrador de entidades estándar consigo excepción:

java.sql.SQLException: 'Infinity' no es un valor numérico numérico o aproximada válida

Por lo que sé, es posible que MySQL no admita números NaN/-INF/+ INF. ¿Hay alguna forma de almacenar esta entidad sin escribir consultas HQL y traducir + INF en nulo (o máximo doble)? Idealmente, me gustaría hacerlo a través del administrador de entidades, como de costumbre.

Gracias de antemano.

Respuesta

3

Los métodos de devolución de llamada del ciclo de vida de la entidad @PrePersist, @PreUpdate se pueden usar aquí para verificar el valor del campo NAN/-INF/+ INF etc & y luego establecer el valor predeterminado en consecuencia.

//-- 

@PrePersist 
@PreUpdate 
private void resetField() { 

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

//-- 
+1

Gracias, eso es todo! Mi solución es usar devoluciones de llamada previas y posteriores y (como lo he elegido) en caso de que + INF configure el campo en Double.MAX_VALUE (es para pre * devoluciones de llamada, para publicarlo se debe hacer MAX -> + INF) –

3

MySQL no parece ser compatible con "infinito". This article escribe que:

Almacenar y recuperar el infinito negativo en una base de datos MySQL se realiza mediante la inserción de un número arbitrariamente grande negativo.

Lo mismo vale para positivo. Other resources también usa 1e500.

En lugar de utilizar el infinito, sugeriría que utilice Float.MAX_VALUE y Float.MIN_VALUE (o equivalentes) Double

Si no puede hacer esto en su código al establecer los valores, lo hace en un @PrePersist como ya se ha sugerido .

+0

Me gusta la idea de usar intencionalmente constantes no infinitas para representar efectivamente el infinito en la aplicación. El método '@ PrePersist' puede sorprender a los usuarios de su código si intentan almacenar infinito pero recuperan algo más. Para mi aplicación, elegí 1e12 (1 billón) como el valor que representa el infinito ya que no tenemos el requisito de almacenar un valor por encima de eso. Me gustó un buen número redondo como 1 billón mejor que Float.MAX_VALUE porque es mucho más fácil escribir en SQL. – David

0

he conseguido este problema mediante la adición de una columna VARCHAR para almacenar la representación de texto de Float.NaN, Float.POSITIVE_INFINITY y Float.NEGATIVE_INFINITY mientras que la columna original almacenará NULL. Luego uso setter y getter para administrar esas dos columnas.

En mi clase @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; 
    } 
} 

Resultado:

| 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  | 
Cuestiones relacionadas