2009-12-13 20 views
16

Estoy intentando crear una clase en un archivo HBM que contenga un Enum como campo.Agregar una enumeración como propiedad de clase en HBM

El HBM es similar a esto:

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

y digamos que esta es la enumeración:

public enum myEnum{ 
    a, b, c; 
} 

El problema es que en el PP que esperaba ver el valor de cadena que enum (a, boc) pero en cambio obtuve los datos brutos de ese campo.

¿Cómo puedo resolver eso?

+1

Véase también http://stackoverflow.com/q/9839553/32453 – rogerdpack

Respuesta

0

Es necesario utilizar un UserType que persistir de manera eficiente: https://www.hibernate.org/265.html

+0

Este es un enfoque bastante desactualizado; no es necesario crear todos esos tipos personalizados adicionales. – ChssPly76

+0

@ ChssPly76: tienes razón. Sigue usando JDK 1.4 aquí. – cherouvim

6

1) Fácil solución: utilizar Hibernate Annotations en lugar de asignaciones basadas en XML. apoyo enumeración is built-in:

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

2) Si no puede utilizar las anotaciones, aún puede utilizar el EnumType que ofrecen en las asignaciones basadas en XML. Usted necesita tener apropiada hibernate-annotations.jar en la ruta de clases durante el despliegue, pero no hay tiempo de compilación dependencia:

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

He intentado la segunda opción pero hace lo mismo. –

+0

"¿Hace lo mismo" que significa qué? ¿Qué quiere decir con "datos sin procesar del campo" almacenados en la base de datos? Tenga en cuenta que el atributo "tipo" anterior debe apuntar a un tipo Hibernate real; no a su clase enum como ha especificado en la pregunta. Este último es ilegal. – ChssPly76

+1

Parece que falta el segundo ejemplo diciéndole qué clase de Enum usar [?] – rogerdpack

3

Por razones que permanecen oscuras, los desarrolladores de Hibernate insisten en mantener el núcleo de Hibernate compatible con pre-Java5, y que significa que no hay soporte enum. Cuando intentas persistir en un campo Enum, simplemente lo serializa y obtienes datos binarios.

Si desea persistir enums utilizando una configuración de asignación .hbm, debe crear y configurar un UserType personalizado para cada tipo de enumeración que desee controlar, lo cual es tedioso e irritante. El Hibernate documentation wiki tiene muchos ejemplos, muchos de los cuales parecen contradecirse, y algunos incluso funcionan.

Sin embargo, si utiliza anotaciones de Hibernate, obtiene soporte completo de java5, incluido el manejo automático de las enumeraciones de java5. Es una verdadera lástima que tengas que hacer una cosa o la otra.

+1

Parece que es posible en estos días ... – rogerdpack

14

Aquí está la solución 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

Dado que Hibernate 4.1.7 consulta utilizando criterios no ya no funciona con este enfoque. No se puede actualizar a la versión más reciente debido a este error. – djmj

+0

Esto funciona bien, pero no lo intentes con una "clase anidada" (una enumeración dentro de otra clase) que no parece funcionar, pero sí una enumeración pública normal. – rogerdpack

0

Sólo edición respuesta @Emmanuel Bourg y añadiendo otra <param> así:

<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 es equivilant a java.sql.Types.VARCHAR

+0

Parece que no necesita especificar "type" o "useNamed" en estos días (al menos para mí, con Postgres, parece ser por defecto legible por humanos normal ...). – rogerdpack

+0

¿Qué es mejor para mejor rendimiento? varchar o int ordinal? Tengo que hacer consultas sobre enum. –

1

Similar a @monim respuesta, pero de manera más 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> 
Cuestiones relacionadas