È possibile utilizzare un enum come valore discriminatore quando si utilizza la strategia di ereditarietà SINGLE_TABLE?Strategia di ereditarietà SINGLE_TABLE utilizzando enum come valore discriminatore
risposta
A mia conoscenza, questo non è possibile con le annotazioni:
- valore discriminatore deve essere di tipo
String
- valore discriminatore deve essere una fase di compilazione costante, ossia valori restituiti da metodi su enums sono non autorizzato.
Yup, quando si definisce discriminatore scelta del annotazioni sono nome e discrimatorType
@DiscriminatorColumn (name="MYDISCRIMINATOR", discriminatorType= DiscriminatorType.INTEGER)
di cui DiscriminatorType possono essere solo:
DiscriminatorType.STRING
DiscriminatorType.CHAR
DiscriminatorType.INTEGER
sfortunato non ho visto ieri, ma ben . Questo è il modo in cui è
E si noti che 'DiscriminatorType' fa riferimento al tipo di DB e non al tipo Java. 'DiscriminatorValue' deve avere ancora un numero tra virgolette come stringa. – TWiStErRob
No, purtroppo non è possibile.
Se si tenta di utilizzare un valore enumeratore come discriminatore, si otterrà un'eccezione di tipo Mancata corrispondenza ("non può convertire da MyEnum in stringa"), poiché gli unici tipi di discriminatore consentiti sono String, Char e Integer. Successivamente, ho provato ad usare il nome e l'ordinale di enum in combinazione con DiscriminatorType.STRING e DiscriminatorType.INTEGER, rispettivamente. Ma questo non ha funzionato o, come l'annotazione @DiscriminatorValue (come qualsiasi altro) richiede un'espressione costante:
Questo non funziona:
@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
}
non funziona neanche:
@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
}
È possibile utilizzare DiscriminatorType.INTEGER
e mappare ciascuna sottoclasse con @DiscriminatorValue("X")
, dove X
deve essere il valore ordinale dell'enumerazione (0,1,2,3 ...).
È deve essere il valore come una stringa costante. Non è possibile utilizzare YourEnum.SOME_VALUE.ordinal()
, perché i valori degli attributi di annotazione devono essere costanti. Sì, è noioso. Sì, è soggetto a errori. Ma funziona.
Questa è una soluzione hacky, tuttavia funziona, inserisco enormi commenti in un 'enum' che viene usato come' DiscriminatorValue'! Anche lo stesso funziona con i nomi enum (con 'DiscriminatorType.String' che potrebbe essere più stabile dell'ordinale. – TWiStErRob
Se quello che stai cercando di ottenere è di non duplicare i valori del discriminatore, c'è una soluzione semplice.
@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";
}
}
Non super elegante, ma meglio che dover mantenere i valori in più posizioni.
Volevo solo migliorare l'ottima risposta di @asa alla soluzione alternativa. Solitamente, spesso ci piace utilizzare la colonna discriminator come attributo della classe astratta e ovviamente mappata con uno enum
. Possiamo ancora usare la soluzione menzionata sopra e forzare alcune consistenze tra i nomi enum
(usati per mappare la colonna) e i valori String
(usati come valori del discrimnator).Qui è il mio suggerimento:
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";
}
}
E per le entità, ecco il codice:
@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 {
…
}
Ancora non non è perfetto, ma un po 'meglio, credo.
- 1. Valore discriminatore sconosciuto "MyEvent"
- 2. Ereditarietà enum
- 3. Enum "Ereditarietà"
- 4. Valore discriminatore sconosciuto C# Mongo
- 5. Come mappare il discriminatore di ereditarietà come chiave composta in Entity Framework?
- 6. Hibernate, ereditarietà di una singola tabella e utilizzo del campo dalla superclasse come colonna discriminatore
- 7. enum valore di DropDownList
- 8. Come @link a un valore Enum utilizzando Javadoc
- 9. Come si inserisce un valore enum Postgres utilizzando Clojure JDBC?
- 10. Come memorizzare il valore di enum nell'arrayist?
- 11. Coppia valore chiave come enum
- 12. Come creare un oggetto figlio di un superoggetto esistente, utilizzando la strategia di ereditarietà JOINED e Hibernate
- 13. Valore iniziale di un Enum
- 14. Più livelli di ereditarietà con Fluent NHibernate utilizzando discriminatori
- 15. Java valore enum personalizzato per enum
- 16. Hibernate 4: persistente colonna discriminatore InheritanceType.JOINED valori
- 17. Conservare nome enum, non il valore nel database utilizzando EBean
- 18. utilizzando enum in switch/case
- 19. Utilizzando GetHashCode per ottenere il valore Enum int
- 20. MasterPage utilizzando Masterpages ed ereditarietà
- 21. utilizzando enum in jython
- 22. Ereditarietà virtuale utilizzando classi vuote
- 23. Enum valore di collisione con il nome enum
- 24. Come provare Provare per valore Enum?
- 25. Come ottenere il valore numerico da Enum?
- 26. Come convertire il valore enum in int?
- 27. Come ottenere un valore personalizzato enum?
- 28. Come passare valore enum in @ Html.ActionLink
- 29. @RequestParam defaultvalue non accetta il valore enum come valore predefinito
- 30. Valore casuale da flag enum
JPA 2.1 non ha cambiato questo? –
Non è JPA, il linguaggio Java non consente di chiamare metodi per i valori di annotazione, vedere: http://docs.oracle.com/javase/specs/jls/se7/html/jls-9.html#jls-9.7 alla 9.7.1, leggi la lista: "Il tipo di' V' è compatibile con l'assegnazione (§5.2) con 'T', e inoltre:". Quindi 'MyEnum.ENUM_CONST.x()' non è valido, 'MyEnum.ENUM_CONST' sarebbe valido, ma' T' è 'String' qui. – TWiStErRob