Czy można używać wyliczenia jako wartości dyskryminującej podczas używania strategii dziedziczenia SINGLE_TABLE?Strategia dziedziczenia SINGLE_TABLE z użyciem wyliczeń jako wartości dyskryminatora
Odpowiedz
O ile mi wiadomo, nie jest to możliwe z adnotacjami:
- wartość dyskryminator musi być typu
String
- wartość dyskryminator musi być kompilacji czas na stałym poziomie, czyli wartości zwracane z metod na teksty stałe są nie dozwolony.
yup, gdy opcję adnotacji w zdefiniowaniu dyskryminator są nazwa i discrimatorType
@DiscriminatorColumn (name="MYDISCRIMINATOR", discriminatorType= DiscriminatorType.INTEGER)
których DiscriminatorType może być tylko:
DiscriminatorType.STRING
DiscriminatorType.CHAR
DiscriminatorType.INTEGER
niefortunne nie widziałem to wczoraj, ale dobrze . Tak to jest
Należy zauważyć, że "DiscriminatorType" odnosi się do typu DB, a nie do typu Java. Wartość "DiscriminatorValue" musi nadal zawierać liczbę w cudzysłowach jako ciąg. – TWiStErRob
Nie, niestety nie możesz.
Jeśli spróbujesz użyć wyliczenia jako wartości dyskryminacyjnej, otrzymasz wyjątek typu niezgodności ("Nie można przekonwertować z MyEnum na ciąg"), ponieważ dozwolone są tylko typy dyskryminatorów: String, Char i Integer. Następnie próbowałem użyć nazwy enum i liczby porządkowej w połączeniu z odpowiednio DiscriminatorType.STRING i DiscriminatorType.INTEGER. Ale to nie działało, jak adnotacji @DiscriminatorValue (jak każdy inny) wymaga stałej ekspresji:
To nie działa:
@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
}
nie działa albo:
@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
}
Można użyć DiscriminatorType.INTEGER
i mapować każdą podklasę za pomocą @DiscriminatorValue("X")
, gdzie X
musi być wartością porządkową wyliczenia (0,1,2,3 ...).
To musi być być wartością jako ciąg stały. Nie można użyć wartości YourEnum.SOME_VALUE.ordinal()
, ponieważ wartości atrybutów adnotacji muszą być stałe. Tak, to jest żmudne. Tak, jest podatny na błędy. Ale działa.
To jest hacky, ale działa, będę umieścić ogromne komentarze w 'enum', który jest używany jako" DiscriminatorValue "! To samo działa z nazwami enum (z 'DiscriminatorType.String', które mogą być bardziej stabilne niż porządkowe. – TWiStErRob
Jeśli próbujesz osiągnąć to, aby nie powielać wartości dyskryminatora, istnieje proste obejście tego problemu.
@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";
}
}
Niezwykle elegancki, ale lepszy niż konieczność zachowania wartości w wielu miejscach.
Po prostu chciałem poprawić doskonałą odpowiedź @asa na temat obejścia tego problemu. Zwykle często lubimy używać kolumny dyskryminacyjnej jako atrybutu klasy abstrakcyjnej i oczywiście mapujemy ją na enum
. Nadal możemy korzystać z wyżej wspomnianego rozwiązania i wymuszać pewne zgodności między nazwami enum
(używanymi do odwzorowania kolumny) i wartościami String
(używanymi jako wartości dyskretatora).Oto moja propozycja:
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";
}
}
I dla podmiotów, oto kod:
@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 {
…
}
Wciąż nie jest doskonały, ale trochę lepiej, myślę.
- 1. Doctrine: Zaktualizuj dyskryminatora dla SINGLE_TABLE Dziedziczenie
- 2. Dlaczego EclipseLink dodaje kolumnę dyskryminatora do powiązanej strategii dziedziczenia?
- 3. Log4net - optymalna strategia w przypadku dziedziczenia
- 4. Hibernate 4: utrzymująca InheritanceType.JOINED kolumnę dyskryminatora wartości
- 5. regresja liniowa z użyciem kategorii jako funkcji
- 6. Używanie wielu wyliczeń NSUInteger jako parametru metody
- 7. gałązka z użyciem zmiennych jako klucz hashowania
- 8. C++ z użyciem „to” jako parametr
- 9. Fold metoda z użyciem listy jako akumulatorze
- 10. Używanie wyliczeń jako niestandardowych atrybutów XML
- 11. Udostępnianie serializacji wartości niestandardowych dla wyliczeń za pomocą JAXB
- 12. Nieznana wartość dyskryminatora "MyEvent"
- 13. Używanie wyliczeń z klasy (C++)
- 14. Jak uzyskać liczbę wyliczeń?
- 15. Łączenie wyliczeń
- 16. Serializacja XML wyliczeń
- 17. Expose wektor jako memoryview użyciem SWIG
- 18. Tworzenie pliku RDF z użyciem pliku txt jako danych wejściowych
- 19. Prevent ADO.NET z użyciem sp_executesql
- 20. wysyłają wartości IR z użyciem podczerwieni emiter LED na Arduino
- 21. Wnioskowanie z użyciem Jeny
- 22. problem z dziedziczenia szablonów
- 23. Strategia wzór z ziaren wiosennych
- 24. mongodb strategia wyszukiwania pełnotekstowego
- 25. Najlepszy sposób obsługi "Rozszerzalnych wyliczeń" w adnotacjach?
- 26. CouchDB strategia wersjonowanie
- 27. Dobra strategia zapewniająca integralność pliku
- 28. Problem z konwertowaniem wyliczeń w C++ \ CLI
- 29. Czy mogę uzyskać dostęp do pola dyskryminatora z php w doctrine2?
- 30. Strategia w Symfony2
JPA 2.1 to się nie zmieniło? –
To nie jest JPA, język Java nie pozwala na wywoływanie metod wartości adnotacji, zobacz: http://docs.oracle.com/javase/specs/jls/se7/html/jls-9.html#jls- 9.7 w 9.7.1, przeczytaj listę: "Typ' V' jest zgodny z przypisaniem (§5.2) z 'T', a ponadto:". Więc 'MyEnum.ENUM_CONST.x()' jest nieprawidłowe, 'MyEnum.ENUM_CONST' będzie poprawne, ale' T' jest tutaj 'String'. – TWiStErRob