you work putting many how hashtags first does comment are allowed java jpa enums hibernate-mapping

java - work - instagram hashtags first comment



JPA enumera el mapeo de tipos. El mejor enfoque (3)

Como es habitual, los tipos de enum de Java tienen los códigos correspondientes y la descripción del nombre. Y las clases de Java que contienen dichos campos, los contienen como Enum:

public enum MyEnum{ SOMEINSTANCE(1, "test1"), SOMEINSTANCE(2, "test2"); private final int code; private final String name; private MyEnum(int code, String name){ this.code = code; this.name = name; } ... helper getter for code and name } @Entity puclic class EnumHolder{ private MyEnum myEnum; }

Soy un novato en JPA, pero deseo tener la tabla '' myEnums '', que se ve así:

code int not null, name varchar(50) not null)

Y en mi tabla enumHolder quiero tener el campo myEnumCode que apunta a la tabla myEnums.

Usar currenlty es compatible tanto con EnumType.ORDINAL como con EnumType.STRING Supongo que no es una buena idea.

Y otra pregunta. ¿Cómo puedo completar la tabla myEnums usando los datos de la clase Java MyEnum ? ¿Como lo harias? El mejor enfoque, por favor.

PD: aquí hay soluciones que puedo ofrecer:

Supongamos que hay una tabla myEnum con fields nombre y code . MyEnum Java MyEnum , que se describe en la pregunta. enumHolder tabla enumHolder necesita tener myEnumCode referencia al campo myEnum.code . Por favor, comenta la solución si no estás de acuerdo.

@Entity @Access(AccessType.FIELD) public class EnumHolder { @Id private int id; @Transient private MyEnum myEnum; … public int getId() { return id; } public void setId(int id) { this.id = id; } public MyEnum getMyEnum() { return MyEnum; } public void setMyEnum(MyEnum myEnum) { this.myEnum = myEnum; } @Access(AccessType.PROPERTY) @Column(name="myEnumCode") protected int getMyEnumForDb() { return myEnum.getCode(); } protected void setMyEnumForDb(int enumCode) { myEnum = MyEnum.getByCode( enumCode); } … }

Por supuesto que hay inconvenientes aquí. Pero por el momento no puedo ver el mejor enfoque. Alternativas con EnumType.ORDINAL y EnumType.STRING, por favor no ofrecer. No quiero escribir aquí todos los problemas que pueden existir con su uso (en Java efectivo se describe sobre el uso de ordinales). Uso de EnumType.STRING No me gusta tampoco porque no permite tener una descripción en la base de datos y solicitarla desde db.

Con respecto a la base de datos fillind. Creo que no es difícil escribir un guión, que borra la tabla myEnum y luego, para cada enunciado de Java, hace insertar en la tabla. Y siempre hazlo durante una fase de implementación.


El mejor enfoque sería mapear una ID única para cada tipo de enumeración, evitando así las trampas de ORDINAL y STRING. Vea esta post que describe 5 formas en que puede mapear una enumeración.

Tomado del enlace de arriba:

1 y 2. Usando @Enumerated

Actualmente hay 2 formas de mapear enumeraciones dentro de sus entidades JPA usando la anotación @Enumerated. Desafortunadamente tanto EnumType.STRING como EnumType.ORDINAL tienen sus limitaciones.

Si usa EnumType.String, el cambio de nombre de uno de sus tipos enum hará que su valor enum no esté sincronizado con los valores guardados en la base de datos. Si usa EnumType.ORDINAL, eliminar o reordenar los tipos dentro de su enumeración hará que los valores guardados en la base de datos se correlacionen con los tipos de enumeraciones incorrectos.

Ambas opciones son frágiles. Si la enumeración se modifica sin realizar una migración de la base de datos, podría poner en riesgo la integridad de sus datos.

3. Retrollamadas del ciclo de vida

Una posible solución sería utilizar las anotaciones de devolución de llamada del ciclo de vida JPA, @PrePersist y @PostLoad. Esto se siente bastante desagradable ya que ahora tendrá dos variables en su entidad. Uno mapeando el valor almacenado en la base de datos, y el otro, la enumeración real.

4. Mapeo de identificación única para cada tipo de enumeración

La solución preferida es asignar su enumeración a un valor fijo, o ID, definido dentro de la enumeración. La asignación a un valor predefinido y fijo hace que su código sea más robusto. Cualquier modificación en el orden de los tipos de enumeraciones, o la refactorización de los nombres, no causará ningún efecto adverso.

5. Usando Java EE7 @Convert

Si está utilizando JPA 2.1, tiene la opción de usar la nueva anotación @Convert. Esto requiere la creación de una clase de convertidor, anotada con @Converter, dentro de la cual definiría qué valores se guardan en la base de datos para cada tipo de enumeración. Dentro de su entidad, usted anotaría su enumeración con @Convert.

Mi preferencia: (Número 4)

La razón por la que prefiero definir mis ID dentro de la enumeración como oposición al uso de un convertidor, es una buena encapsulación. Solo el tipo de enumeración debe conocer su ID, y solo la entidad debe saber cómo correlaciona la enumeración con la base de datos.

Vea la post original para el ejemplo de código.


Puede agregar un campo enumerado a su entidad usando @Enumerated . Lo mejor de todo es que quiere tener su pastel y comérselo también. Por consistencia, sería mejor elegir EnumType.ORDINAL o EnumType.STRING .

Ambos tienen sus ventajas y desventajas, que se enumeran en este sitio . La gran diferencia parece ser con los pedidos: si tiene EnumType.ORDINAL configurado, podría tener problemas al actualizar su enumeración.

Lo alentaría a reconsiderar la forma en que desea diseñar su mesa. La cadena y el entero esencialmente almacenan la misma información, cuál es el valor enumerado, y puede obtenerla de la base de datos sin demasiado alboroto. Sería mejor tener una id como clave principal en la tabla, luego tener el tipo enumerado como cadena o valor ordinal, teniendo en cuenta las advertencias del enlace de arriba.


@Column(name = "MY_TYPE") @Enumerated(EnumType.STRING) private MyType type; enum MyType { type_1 type_2 }

luego crea tu columna como sigue:

TYPE_ID VARCHAR(20) NOT NULL DEFAULT ''TYPE_1'' CHECK (TYPE_ID IN (''TYPE_1'', ''TYPE_2'')))

esto resolvió mi problema