7
votes

Java Enum ToString ToString ()

Je n'ai jamais vraiment utilisé de classes Java Enum avant de faire des valeurs constantes, j'ai généralement utilisé l'approche "finale publique" dans le passé. J'ai commencé à utiliser un énumé maintenant et je remplace la méthode Tostring () pour renvoyer une valeur différente de celle du nom Enum.

J'ai du code JPA dans lequel je crée une typédoise avec des paramètres nommés, l'un des qui est une représentation de chaîne de la valeur Enum. Si je définissais simplement le paramètre à l'aide de Status.active, je reçois la valeur «A» appropriée, mais une exception est lancée, car son type est en réalité plutôt que de la chaîne. Cela ne fonctionne que si j'appelle explicitement la méthode Tostring (). Je pensais que simplement remplacer la méthode Tostring () entraînerait un type de chaîne renvoyé, quel que soit le type de classe. P>

C'est l'ENUM: P>

    TypedQuery<MechanicTimeEvent> query = entityManager().createQuery("SELECT o FROM MechanicTimeEvent o WHERE o.id.mechanicNumber = :mechanicNumber AND o.id.status = :status", MechanicTimeEvent.class);
    query.setParameter("mechanicNumber", mechanicNumber);
    query.setParameter("status", Status.ACTIVE.toString());


5 commentaires

Peut ajouter la cartographie de ce champ à la question?


Si vous recherchez un moyen plus concis de l'écrire, Query.setParameter ("statut", statut.active + ""); fonctionnera.


Est-ce que le champ de votre @entity de type Statut et est annoté avec @enumerated (enumtype.string) ? Si oui, vous devriez pouvoir utiliser Enums dans les requêtes, tout va bien.


ici et ICI Des problèmes similaires et des réponses ont déjà été discutés.


Le champ de mon @entity est simplement une chaîne, mais ce ne sera jamais une valeur d'A, P ou F, donc j'ai créé une énumération pour ces valeurs afin que dans le code, je pourrais utiliser quelque chose comme Statut.actif et il serait plus descriptif. J'ai pensé à remplacer la méthode Tostring () pour renvoyer la valeur réelle renvoyerait un type de chaîne sans appeler explicitement de tostring ().


6 Réponses :


0
votes

Ceci ou vous implémentez simplement un getter pour la valeur: xxx pré>

et vous l'appelez dans votre code: p>

query.setParameter("status", Status.ACTIVE.getValue());


0 commentaires

0
votes

Tostring est juste une méthode ordinaire de l'objet qui est explicitement appelée par certaines méthodes telles que PrintStream.println (rappelez-vous System.out.println) ou examiné lors de la concaténation à l'aide de l'opérateur +. Chaque méthode n'a pas besoin de mettre en œuvre ce comportement.

Je vous suggère d'utiliser un nom de méthode plus descriptif comme getvalue et appelez-le explicitement au lieu de remplacer Tostring


0 commentaires

3
votes

Si je comprends votre question correctement, vous devriez faire la cartographie enum. De cette manière, les États sont stockés comme État et JPA traiterait l'énum basé sur son nom A, P, F). XXX

De cette manière, vous pouvez simplement passer le statut sans invoquer la totring () Méthode à JPA. La méthode .Name () sur l'ENUM sera invoquée automatiquement pour obtenir le code d'état pour la persistance.


4 commentaires

Vous ne devriez pas réduire les noms de champs à une lettre simplement parce que c'est la forme de votre base de données / quelles que soient les utilisations. Vous ne pouvez pas simplement remplacer .name () ?


Enum.name () La méthode est finale, vous ne pouvez donc pas être remplacé.


Le but de le faire comme ça que j'ai eu, c'est donc si quelqu'un d'autre lit le code, Status.active est plus évident que le statut.a.


Comme le Java API Docs < / a> points en gras: la plupart des programmeurs doivent utiliser la touche Tostring () . Remplacer tostring () est le bon chemin.



3
votes

est le champ Statut de la haricot mécanicictime d'un énumé? Sinon, je suggérerais de le modifier au type Enum type Statut .

Vous pouvez l'annoter avec @enumerated (EnumType.string)

En outre, je suggérerais de supprimer la partie de la valeur de votre énumé et Utilisez simplement les noms tels que: xxx


5 commentaires

Ce n'était pas un type d'enum, alors je l'ai changé pour taper le statut et ajouté l'annotation que vous avez suggérée. Je pense que ça fait l'affaire. Ce qui est étrange maintenant, c'est si aucun record n'est trouvé par ma requête, alors cela fonctionne bien, mais s'il trouve un enregistrement, alors que OpenJPA jette une erreur argumentException et me dit de vérifier la syntaxe de ma requête, je ne sais pas pourquoi.


Avez-vous utilisé la valeur Enum au lieu de la chaîne?: Ie Query.setParameter ("Statut", Status.active)


En réalité, le problème est que, puisque la base de données stocke uniquement les valeurs, c'est-à-dire: A, P ou F, puis lors de la création d'une instruction SELECT, OpenJPA transmet la valeur A renvoyée de la requête à la valeur de l'ENUM. Comme il ne trouve pas un dans l'énum, ​​cela jette l'exception. La valeur de la méthode est définitive, donc je ne peux pas le remplacer.


Ah ouais. Peut-être un inconvénient, mais lorsque vous utilisez Enums en combinaison avec JPA, seuls les noms comptent, pas les valeurs. Personnellement, je voudrais simplement supprimer la propriété valeur et n'utilisez que les noms de clé de l'ENUM. Voir ma réponse bjotifiée ;-)


Hey Lauwie, j'ai compris comment traiter avec ça. J'ai fini par passer d'OpenJPA à Eclipselink. Avec EclipsElink, je suis capable de définir mon énumé aussi simple que vous l'avez sans constructeur, puis dans mon domaine d'entité, j'ajoute quelques annotations Eclipselink pour avoir pris soin de la conversion. Vérifiez le gist que je viens de poster. Gist.github.com/1287713



-1
votes
java.lang.Enum said clearly:
 /**
 * Returns the name of this enum constant, exactly as declared in its
 * enum declaration.
 * 
 * <b>Most programmers should use the {@link #toString} method in
 * preference to this one, as the toString method may return
 * a more user-friendly name.</b>  This method is designed primarily for
 * use in specialized situations where correctness depends on getting the
 * exact name, which will not vary from release to release.
 *
 * @return the name of this enum constant
 */
 public final String name()
just like the loft say ,you can use "name" method to get the name.
also you can use toString() method.of course it is just name of this enum constant.

0 commentaires

6
votes
public enum Status {
    ACTIVE,
    PENDING,
    FINISHED;

    @Override
    public String toString() {
        String name = "";
        switch (ordinal()) {
        case 0:
            name = "A";
            break;
        case 1:
            name = "P";
            break;
        case 2:
            name = "F";
            break;
        default:
            name = "";
            break;
        }
        return name;
    }
};

2 commentaires

Cette mise en œuvre () Tostring () nécessite une trop grande maintenance, en particulier si les noms d'ENUM seront déjà ajoutés à l'avenir. Il est préférable d'attribuer une valeur de chaîne sur l'instanciation et de retourner cela à la place.


... comme la solution de la question fournit. Ce code est plus lisible et la localité entre le "mappage de chaîne" ( actif ("A" ("A") ), évite également le code d'exécution avec les typos (c.-à-d.: case 3: nom = "E" au lieu de Case 2: Nom = "F" ). En outre, la valeur par défaut par défaut n'a pas de sens.