2009-12-13 5 views
16

J'essaie de créer une classe dans un fichier HBM contenant un champ Enum.Ajout d'une énumération en tant que propriété de classe dans HBM

Le HBM est semblable à ceci:

<class name="a.b.c.myObject" table="OBJECT" > 
     <property name="myEnum" column="EXAMPLE" type="a.b.c.myEnum" /> 
</class> 

et disons que c'est le Enum:

public enum myEnum{ 
    a, b, c; 
} 

Le problème est que dans le DB je m'y attendais à voir la valeur de chaîne de cette enum (a, b ou c) mais j'ai obtenu les données brutes de ce champ.

Comment puis-je résoudre ce problème?

+1

Voir aussi http://stackoverflow.com/q/9839553/32453 – rogerdpack

Répondre

0

Vous devez utiliser UserType persister efficacement que: https://www.hibernate.org/265.html

+0

Il s'agit d'une approche plutôt obsolète; la création de tous ces types personnalisés supplémentaires est inutile. – ChssPly76

+0

@ ChssPly76: Vous avez raison. Toujours en utilisant JDK 1.4 ici. – cherouvim

6

1) Solution facile: utiliser Hibernate Annotations au lieu d'applications XML. soutien Enum is built-in:

@Entity 
public class MyObject { 
    @Enumerated(EnumType.STRING) 
    @Column(name="EXAMPLE") 
    private MyEnum myEnum; 
} 

2) Si vous ne pouvez pas utiliser les annotations, vous pouvez toujours utiliser la EnumType qu'ils fournissent dans les correspondances XML. Vous avez besoin d'avoir hibernate-annotations.jar approprié dans votre classpath au cours du déploiement, mais il n'y a pas de dépendance à la compilation:

<class name="a.b.c.myObject" table="OBJECT" > 
    <property name="myEnum" column="EXAMPLE" type="org.hibernate.type.EnumType"/> 
</class> 
+0

J'ai essayé la deuxième option mais elle fait la même chose. –

+0

"Est-ce la même" qui signifie quoi? Qu'entendez-vous par "données brutes du terrain" stockées dans la base de données? Notez que l'attribut "type" ci-dessus doit pointer vers un type Hibernate réel; pas à votre classe enum comme vous l'avez spécifié dans la question. Ce dernier est illégal. – ChssPly76

+1

Le deuxième exemple semble manquer de dire quelle classe Enum utiliser [?] – rogerdpack

3

Pour des raisons qui restent obscures, les développeurs Hibernate insistent sur le fait sur le maintien de la base Hibernate compatible avec pré-Java5, et que signifie pas de support enum. Lorsque vous essayez de conserver un champ Enum, il ne fait que le sérialiser et vous obtenez des données binaires. Si vous souhaitez conserver les enums en utilisant une configuration de mappage .hbm, vous devez créer et configurer un UserType personnalisé pour chaque type d'énumération que vous souhaitez gérer, ce qui est fastidieux et irritant. Le Hibernate documentation wiki a beaucoup d'exemples, dont beaucoup semblent se contredire, et certains d'entre eux fonctionnent même. Cependant, si vous utilisez les annotations Hibernate, vous bénéficiez de la prise en charge complète de java5, y compris la gestion automatique des enums de Java5. C'est juste une vraie honte que vous ayez à faire l'un ou l'autre.

+1

On dirait que c'est possible ces jours-ci ... – rogerdpack

14

Voici la solution avec Hibernate 3.6.x:

<class name="a.b.c.myObject" table="OBJECT"> 
    <property name="myEnum" column="EXAMPLE"> 
    <type name="org.hibernate.type.EnumType"> 
     <param name="enumClass">a.b.c.myEnum</param> 
    </type>  
    </property> 
</class> 
+0

Depuis Hibernate 4.1.7 demander en utilisant des critères ne fonctionne plus avec cette approche. Impossible de mettre à jour vers la version la plus récente à cause de ce bogue. – djmj

+0

Cela fonctionne bien, mais ne l'essayez pas avec une "classe imbriquée" (une énumération à l'intérieur d'une autre classe) qui ne semble pas fonctionner mais un enum public normal. – rogerdpack

0

édition Il suffit de répondre @Emmanuel Bourg et en ajoutant un autre <param> comme ceci:

<class name="a.b.c.myObject" table="OBJECT"> 
    <property name="myEnum" column="EXAMPLE"> 
     <type name="org.hibernate.type.EnumType"> 
      <param name="enumClass">a.b.c.myEnum</param> 
      <param name="type">12</param> 
     </type>  
    </property> 
</class> 

12 est equivilant à java.sql.Types.VARCHAR

+0

Semble que vous n'avez pas besoin de spécifier "type" ou "useNamed" ces jours-ci (au moins pour moi avec Postgres, il semble que par défaut normal lisible par l'homme ...). – rogerdpack

+0

Quel est le meilleur pour de meilleures performances? varchar ou int ordininal? Je dois faire des requêtes sur enum. –

1

Similaire à @monim réponse, mais de façon plus élégante:

<class name="a.b.c.myObject" table="OBJECT"> 
    <property name="myEnum" column="EXAMPLE"> 
     <type name="org.hibernate.type.EnumType"> 
      <param name="enumClass">a.b.c.myEnum</param> 
      <param name="useNamed">true</param> 
     </type>  
    </property> 
</class> 
Questions connexes