मैं java.util का मामूली संशोधन का उपयोग कर रहा हूं।RegularEnumSet एक लगातार EnumSet के लिए:
@MappedSuperclass
@Access(AccessType.FIELD)
public class PersistentEnumSet<E extends Enum<E>>
extends AbstractSet<E> {
private long elements;
@Transient
private final Class<E> elementType;
@Transient
private final E[] universe;
public PersistentEnumSet(final Class<E> elementType) {
this.elementType = elementType;
try {
this.universe = (E[]) elementType.getMethod("values").invoke(null);
} catch (final ReflectiveOperationException e) {
throw new IllegalArgumentException("Not an enum type: " + elementType, e);
}
if (this.universe.length > 64) {
throw new IllegalArgumentException("More than 64 enum elements are not allowed");
}
}
// Copy everything else from java.util.RegularEnumSet
// ...
}
इस वर्ग अब मेरी enum सेट के सभी के लिए आधार है:
@Embeddable
public class InterestsSet extends PersistentEnumSet<InterestsEnum> {
public InterestsSet() {
super(InterestsEnum.class);
}
}
और वह सेट मैं अपने इकाई में उपयोग कर सकते हैं:
@Entity
public class MyEntity {
// ...
@Embedded
@AttributeOverride(name="elements", [email protected](name="interests"))
private InterestsSet interests = new InterestsSet();
}
लाभ:
- एक प्रकार सुरक्षित और अपने कोड में performant enum सेट के साथ कार्य करना (विवरण के लिए
java.util.EnumSet
देखें)
- सेट सिर्फ एक डेटाबेस में संख्यात्मक स्तंभ है
- सब कुछ है सादा जेपीए (कोई प्रदाता विशिष्ट कस्टम प्रकार)
- एक ही प्रकार के नए क्षेत्रों के लिए आसान (और कम) घोषणा, अन्य समाधान
कमियां के साथ तुलना में:
- कोड दोहराव (
RegularEnumSet
और PersistentEnumSet
लगभग समान हैं)
- आप अपने
PersistenEnumSet
में EnumSet.noneOf(enumType)
का परिणाम लपेट सकता है, AccessType.PROPERTY
घोषित करने और जो प्रतिबिंब का उपयोग दो पहुँच तरीकों को पढ़ने के लिए प्रदान करते हैं और elements
क्षेत्र लिखने
- प्रत्येक एनम कक्षा के लिए एक अतिरिक्त सेट क्लास की आवश्यकता होती है जिसे लगातार सेट
- में संग्रहीत किया जाना चाहिए यदि आपका दृढ़ता प्रदाता समर्थक एक सार्वजनिक निर्माता बिना ts embeddables, आप
PersistentEnumSet
को @Embeddable
जोड़ सकता है और अतिरिक्त वर्ग (... interests = new PersistentEnumSet<>(InterestsEnum.class);
)
- आप एक
@AttributeOverride
का उपयोग करना चाहिए छोड़, मेरे उदाहरण के रूप में दी है, यदि आप एक से अधिक PersistentEnumSet
में मिल गया है आपकी इकाई (अन्यथा दोनों एक ही कॉलम "तत्वों" में संग्रहीत की जाएंगी)
- कन्स्ट्रक्टर में प्रतिबिंब के साथ
values()
का उपयोग इष्टतम नहीं है (विशेष रूप से प्रदर्शन को देखते समय), लेकिन दो अन्य विकल्पों में भी उनकी कमी है :
- एक कार्यान्वयन
EnumSet.getUniverse()
तरह समझना बनाता है एक sun.misc
वर्ग
- पैरामीटर के रूप में मान सरणी प्रदान के उपयोग जोखिम है जो दिए गए मानों सही लोगों
- केवल 64 मूल्यों के साथ enums का समर्थन कर रहे नहीं हैं (यह है कि वास्तव में एक दोष?)
- आप BigInteger इस्तेमाल कर सकते हैं बजाय
- यह एक मापदंड क्वेरी में तत्वों क्षेत्र का उपयोग करने के लिए आसान नहीं है या JPQL
- आप द्विआधारी ऑपरेटर या उचित कार्यों के साथ बिटमास्क स्तंभ, इस्तेमाल कर सकते हैं यदि आपके डेटाबेस का समर्थन करता है कि
स्रोत
2015-01-27 22:27:11
यदि कोई इसे अब पढ़ता है ... @CollectionOfElements अब बहिष्कृत है, इसके बजाय उपयोग करें: @ElementCollection –
आप इस प्रश्न के उत्तरदाता में एक नमूना पा सकते हैं: http://stackoverflow.com/q/3152787/363573 – Stephan
आप हाइबरनेट का उल्लेख किया, मैंने सोचा कि यह जवाब विक्रेता-विशिष्ट हो सकता है लेकिन मुझे नहीं लगता कि यह तब तक नहीं है जब तक कि जॉइनटेबल का उपयोग अन्य कार्यान्वयन में परेशानी का कारण न हो। मैंने जो देखा है, उससे मेरा मानना है कि कलेक्शनटेबल का इस्तेमाल इसके बजाय किया जाना चाहिए। यही कारण है कि मैंने अपने जवाब में उपयोग किया और यह मेरे लिए काम करता है (हालांकि हाँ, मैं अभी भी हाइबरनेट का उपयोग कर रहा हूं।) – spaaarky21