¿Es posible usar una enumeración como valor discriminador cuando se usa la estrategia de herencia SINGLE_TABLE?Estrategia de herencia SINGLE_TABLE usando enums como valor de discriminador
Respuesta
Que yo sepa, esto no es posible con las anotaciones:
- valor discriminador tiene que ser de
String
- valor discriminador debe ser un tiempo de compilación constante, es decir, valores de retorno de métodos en las enumeraciones son No permitido.
Sí, cuando se define discriminador opción de la anotación son nombre y discrimatorType
@DiscriminatorColumn (name="MYDISCRIMINATOR", discriminatorType= DiscriminatorType.INTEGER)
de los cuales DiscriminatorType sólo pueden ser:
DiscriminatorType.STRING
DiscriminatorType.CHAR
DiscriminatorType.INTEGER
desafortunado que no vieron esto ayer, pero bien . Así es
Y tenga en cuenta que 'DiscriminatorType' hace referencia al tipo de base de datos y no al tipo de Java. 'DiscriminatorValue' debe tener un número entre comillas como String. – TWiStErRob
No, desafortunadamente no se puede.
Si intenta utilizar una enumeración como valor discriminador, obtendrá una excepción de Tipo no coincidente ("no se puede convertir de MyEnum a Cadena"), ya que los únicos tipos de discriminador permitidos son Cadena, Carácter y Entero. A continuación, intenté usar el nombre y el ordinal de una enumeración combinados con DiscriminatorType.STRING y DiscriminatorType.INTEGER, respectivamente. Pero esto no funcionaba bien, como la anotación @DiscriminatorValue (como cualquier otra) requiere una expresión constante:
esto no funciona:
@Entity
@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name="FREQUENCY",
discriminatorType=DiscriminatorType.STRING
)
public abstract class Event {}
@Entity
@DiscriminatorValue(value=Frequency.WEEKLY.name())
public class WeeklyEvent extends Event {
// Exception: The value for annotation attribute DiscriminatorValue.value must be a constant expression
}
No funciona bien:
@Entity
@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name="FREQUENCY",
discriminatorType=DiscriminatorType.INTEGER
)
public abstract class Event {}
@Entity
@DiscriminatorValue(value=Frequency.WEEKLY.ordinal())
public class WeeklyEvent extends Event {
// Exception: The value for annotation attribute DiscriminatorValue.value must be a constant expression
}
Puede usar DiscriminatorType.INTEGER
, y asignar cada subclase a @DiscriminatorValue("X")
, donde X
debe ser el valor ordinal de la enumeración (0,1,2,3 ...).
Es debe ser el valor como una cadena constante. No puede usar YourEnum.SOME_VALUE.ordinal()
, porque los valores de los atributos de anotación deben ser constantes. Sí, es tedioso. Sí, es propenso a errores. Pero funciona.
Esta es una solución hacky, sin embargo, funciona, pondría enormes comentarios en un 'enum' que se utiliza como un' DiscriminatorValue'! También lo mismo funciona con nombres enum (con 'DiscriminatorType.String' que puede ser más estable que el ordinal. – TWiStErRob
Si lo que intenta lograr es no duplicar los valores del discriminador, existe una solución simple.
@Entity
@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name="FREQUENCY",
discriminatorType=DiscriminatorType.STRING
)
public abstract class Event {
}
@Entity
@DiscriminatorValue(value=Frequency.Values.WEEKLY)
public class WeeklyEvent extends Event {
…
}
public enum Frequency {
DAILY(Values.DAILY),
WEEKLY(Values.WEEKLY),
MONTHLY(Values.MONTHLY);
private String value;
…
public static class Values {
public static final String DAILY = "D";
public static final String WEEKLY = "W";
public static final String MONTHLY = "M";
}
}
No es muy elegante, pero es mejor que tener que mantener los valores en varios lugares.
Solo quería mejorar la excelente respuesta de @asa sobre la solución. Por lo general, a menudo nos gusta utilizar la columna de discriminador como un atributo de la clase abstracta, y mapeamos con un enum
, por supuesto. Todavía podemos utilizar la solución mencionada anteriormente y forzar algunas consistencias entre los nombres enum
(utilizados para asignar la columna) y los valores String
(utilizados como valores del discriminador).Aquí está mi sugerencia:
public enum ELanguage {
JAVA(Values.JAVA), GROOVY(Values.GROOVY);
private ELanguage (String val) {
// force equality between name of enum instance, and value of constant
if (!this.name().equals(val))
throw new IllegalArgumentException("Incorrect use of ELanguage");
}
public static class Values {
public static final String JAVA= "JAVA";
public static final String GROOVY= "GROOVY";
}
}
Y para las entidades, aquí está el código:
@Entity
@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name="LANGUAGE_TYPE", discriminatorType=DiscriminatorType.STRING)
public abstract class Snippet {
// update/insert is managed by discriminator mechanics
@Column(name = "LANGUAGE_TYPE", nullable = false, insertable = false, updatable = false)
@Enumerated(EnumType.STRING)
public ELanguage languageType
}
@Entity
@DiscriminatorValue(value=ELanguage.Values.JAVA)
public class JavaSnippet extends Snippet {
…
}
aún no es perfecto, pero un poco mejor, creo.
- 1. Doctrine: Update discriminator for SINGLE_TABLE Herencia
- 2. Hibernate: org.hibernate.WrongClassException, la herencia SINGLE_TABLE y DiscriminatorFormula
- 3. Valor discriminador desconocido 'MyEvent'
- 4. Cómo correlacionar el discriminador de herencia como clave compuesta en Entity Framework?
- 5. JPA: Herencia - valor discriminador no se tiene en cuenta en el SQL generado
- 6. ¿Por qué EclipseLink está agregando una columna discriminatoria para la estrategia de herencia unida?
- 7. Log4net: estrategia óptima al usar la herencia
- 8. ¿Puedo eliminar la columna del discriminador en una herencia de tabla única de Hibernate?
- 9. C# Enums: valor anulable o 'desconocido'?
- 10. Spring -Mongodb almacenamiento/recuperación de enums como int no string
- 11. DataTrigger en Enums como el valor de activación en un WPF Style
- 12. Código EF Primero "Nombre de columna inválido 'Discriminador'" pero no herencia
- 13. enums de Java ordenando
- 14. DataContractJsonSerializer y Enums
- 15. Eficiencia de la estrategia de herencia de tabla por subclase de Hibernate
- 16. Ampliación de Java Enums
- 17. Consulta por discriminador en NHibernate
- 18. ¿puede declararse C# enums como de tipo bool?
- 19. MongoDB deserialización Con Discriminador Edición
- 20. Múltiples niveles de herencia con Fluent NHibernate usando discriminadores
- 21. deserializing enums
- 22. usando hermana herencia
- 23. Java herencia, usando Builder
- 24. ¿Cómo almacena MySQL Store Enums?
- 25. Hibernación Subclase que tiene múltiples valores de discriminador
- 26. ¿Puedo comparar enums de MySQL?
- 27. Patrón de estrategia e inyección de dependencia usando Unity
- 28. Estrategia de registro
- 29. Diseño pitónico sin enums
- 30. Herencia de atributos en python usando __init__
JPA 2.1 no ha cambiado esto? –
No es APP, el lenguaje Java no permite que llame a métodos para valores de anotación, consulte: http://docs.oracle.com/javase/specs/jls/se7/html/jls-9.html#jls-9.7 en 9.7.1, lea la lista: "El tipo de' V' es compatible con la asignación (§5.2) con 'T', y además:". Entonces 'MyEnum.ENUM_CONST.x()' no es válido, 'MyEnum.ENUM_CONST' sería válido, pero' T' es 'String' aquí. – TWiStErRob