Question

Je simple entité JPA suivante:

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

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

et b peut être mis à Double.POSITIVE_INFINITY. Lorsque je tente d'entité magasin avec double jeu à + INF dans la base de données (MySQL) en utilisant le gestionnaire de l'entité standard que je reçois exception:

java.sql.SQLException: 'Infinity' est pas une valeur numérique ou numérique approximative valide

Pour autant que je sais MySQL ne supporte pas le nombre NaN / -INF / + INF. Est-il possible de stocker cette entité sans écrire des requêtes HQL et traduction + INF en nul (ou double max)? Idéalement, je voudrais le faire via le gestionnaire d'entités comme d'habitude.

Merci à l'avance.

Était-ce utile?

La solution

Entité méthodes de rappel de cycle de vie @PrePersist, @PreUpdate peuvent être utilisés ici pour vérifier la valeur du champ NAN / -INF / + INF etc et puis définir la valeur par défaut en conséquence.

 //--

 @PrePersist  
 @PreUpdate  
 private void resetField() {

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

 //--

Autres conseils

MySQL ne semble pas soutenir « l'infini ». les écritures de cet article que:

stockage et la récupération de l'infini négatif dans une base de données MySQL est réalisée en insérant un nombre arbitrairement grand négatif.

Même va pour le positif. Autres ressources utilisent également 1e500.

Au lieu d'utiliser l'infini, je suggère que vous utilisez Float.MAX_VALUE et Float.MIN_VALUE (ou équivalents Double)

Si vous ne pouvez pas faire cela dans votre code lorsque vous définissez les valeurs, faites-le dans un @PrePersist comme cela a déjà suggéré.

Je géré ce problème en ajoutant une colonne varchar pour stocker la représentation textuelle de Float.NaN, Float.POSITIVE_INFINITY et Float.NEGATIVE_INFINITY tandis que la colonne d'origine stockera NULL. Puis-je utiliser le compositeur et le getter à faire gérer ces deux colonnes.

Dans ma classe @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;
    }
}

Résultat:

| 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        |
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top