web-dev-qa-db-fra.com

Enum dans Hibernate, persistant en tant qu'enum

Dans ma base de données MySQL, il y a la colonne "gender enum ('male', 'female')"

J'ai créé mon énumération "com.mydomain.myapp.enums.Gender", et dans mon entité Person, je suis défini "Gender gender".

Maintenant, je voudrais garder le type enum dans ma base de données MySQL, mais quand je lance mon application, j'obtiens:

Type de colonne incorrect dans MyApp.Person pour le sexe de la colonne. Trouvé: enum, attendu: entier

Pourquoi est-ce? Ce serait l'équivalent comme si j'avais annoté mon "Gender gender" avec "@Enumerated (EnumType.ORDINAL)", ce que je n'ai pas. EnumType ne semble pouvoir être ORDINAL ou STRING, alors comment puis-je spécifier qu'il doit traiter le champ comme une énumération, pas comme un int? (pas qu'il y ait beaucoup de différence, mais assez pour que cela le contrarie.)

38
niklassaers

Ma compréhension est que le type d'énumération MySQL est très propriétaire et n'est pas bien pris en charge par Hibernate, voir ce commentaire de Gavin King (ce problème connexe est un peu différent mais ce n'est pas la partie importante).

Donc, je pense en fait que vous devrez utiliser votre propre UsereType et je recommanderais d'utiliser la Solution flexible - version de travail à partir de Java 5 EnumUserType (voir Appfuse's Java 5 Enums Persistence with Hibernate pour un exemple).

Personnellement, j'oublierais juste l'idée d'utiliser l'énumération MySQL, je ne suis pas convaincu que les "avantages" en valent la peine (voir cette réponse pour plus de détails).

26
Pascal Thivent

Si vous donnez à Hibernate une définition de colonne, il n'essaiera pas d'en deviner une:

@Column(columnDefinition = "enum('MALE','FEMALE')")
@Enumerated(EnumType.STRING)
private Gender gender;

Si vous ne comptez pas sur Hibernate pour générer votre schéma pour une raison quelconque, vous n'avez même pas à fournir de vraies valeurs pour la columnDefinition. De cette façon, vous supprimez une instance où vous devez garder les valeurs synchronisées. Gardez simplement votre Java et votre script Liquibase ou SQL synchronisés:

@Column(columnDefinition = "enum('DUMMY')")
@Enumerated(EnumType.STRING)
private ManyValuedEnum manyValuedEnum;
24
Jimmie Fulton

Essayez d'utiliser @Enumerated (EnumType.STRING) et définissez votre énumération comme ceci

enum Gender {
  male,
  female
}

Notez les valeurs minuscules.

Cela fonctionnera au moins avec les colonnes VARCHAR. Il stockera l'énumération sous forme de chaîne "mâle" ou "femelle".

17
Juha Syrjälä

je ne sais pas pourquoi ce n'est pas dans la documentation Hibernate mais vous pouvez le faire

<property name="type" column="type" not-null="true">
    <type name="org.hibernate.type.EnumType">
        <param name="enumClass">com.a.b.MyEnum</param>
        <param name="type">12</param>
        <!-- 12 is Java.sql.Types.VARCHAR -->
    </type> 
</property>
5
Kikoz

Pas pour ce cas, mais si quelqu'un utilise le mappage XML:

<property name="state" column="state" not-null="true">
  <type name="org.hibernate.type.EnumType">
    <param name="enumClass">com.myorg.persistence.data.State</param>
  </type>
</property>

Le type de colonne de base de données doit être numérique, par exemple tinyint sur un mysql pour rendre possible la lecture des valeurs ordinales.

4
Christof Aenderl