2009-12-13 15 views
16

Sto provando a creare una classe nel file HBM che contiene un Enum come campo.Aggiunta di un enum come proprietà di classe in HBM

La HBM è simile a questo:

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

e diciamo che questo è l'Enum:

public enum myEnum{ 
    a, b, c; 
} 

Il problema è che nel DB mi aspettavo di vedere il valore stringa di quel enum (a, b o c) ma invece ho ottenuto i dati grezzi di quel campo.

Come posso risolvere quello?

+1

Vedere anche http://stackoverflow.com/q/9839553/32453 – rogerdpack

risposta

0

È necessario utilizzare un UserType a persistere in modo efficiente: https://www.hibernate.org/265.html

+0

Questo è un approccio piuttosto obsoleto; la creazione di tutti quei tipi extra personalizzati non è necessaria. – ChssPly76

+0

@ ChssPly76: hai ragione. Sto ancora usando JDK 1.4 qui. – cherouvim

6

1) Soluzione facile: usare Hibernate Annotations invece di mappature basate su XML. Supporto Enum is built-in:

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

2) Se non è possibile utilizzare le annotazioni, è comunque possibile utilizzare l'EnumType che forniscono nelle mappature basate su XML. Si ha bisogno di avere adeguata hibernate-annotations.jar nel classpath durante la distribuzione, ma non c'è tempo di compilazione delle dipendenze:

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

Ho provato la seconda opzione ma fa lo stesso. –

+0

"Fa lo stesso" che significa cosa? Cosa intendevi per "dati grezzi del campo" memorizzati nel database? Nota che l'attributo "type" qui sopra deve puntare ad un tipo di Hibernate effettivo; non alla tua classe enum come hai specificato nella domanda. Quest'ultimo è illegale. – ChssPly76

+1

Il secondo esempio sembra mancare dicendogli quale classe Enum usare [?] – rogerdpack

3

Per ragioni che rimangono oscure, gli sviluppatori Hibernate insistono a mantenere il nucleo di Hibernate compatibile con pre-Java5, e che significa nessun supporto enum. Quando si tenta di mantenere un campo Enum, lo serializza semplicemente e si ottengono dati binari.

Se si desidera mantenere l'enumerazione utilizzando una configurazione di mappatura .hbm, è necessario creare e configurare un numero personalizzato UserType per ciascun tipo di enum che si desidera gestire, il che è noioso e irritante. Lo Hibernate documentation wiki ha un sacco di esempi, molti dei quali sembrano contraddirsi l'un l'altro e alcuni addirittura funzionano.

Se si utilizzano le annotazioni di ibernazione, si ottiene il supporto completo di java5, inclusa la gestione automatica delle enumerazioni java5. È solo un vero peccato che tu debba fare l'uno o l'altro.

+1

Sembra che sia possibile in questi giorni ... – rogerdpack

14

Ecco la soluzione con 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

Poiché Hibernate 4.1.7 richiede i criteri di ricerca non funziona più con questo approccio. Impossibile aggiornare alla versione più recente a causa di questo bug. – djmj

+0

Funziona bene, ma non provarlo con una "classe nidificata" (un enum all'interno di un'altra classe) che non sembra funzionare, ma un normale enume pubblico lo ha fatto. – rogerdpack

0

semplicemente modificando @Emmanuel Bourg risposta e l'aggiunta di un altro <param> come questo:

<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 è l'equivalente di java.sql.Types.VARCHAR

+0

Sembra che non sia necessario specificare "type" o "useNamed" in questi giorni (almeno per me con Postgres sembra essere normalmente leggibile come normale ...). – rogerdpack

+0

Quale è meglio per prestazioni migliori? varchar o int ordinale? Devo fare domande su enum. –

1

Simile alla risposta @monim, ma in modo più elegante:

<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> 
Problemi correlati