我對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
// ...
}
現在這個類是我所有的枚舉集基地:
@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();
}
優點:
- 在你的代碼類型安全和高性能的枚舉集工作(參見
java.util.EnumSet
的描述)
- 集是在數據庫中只有一個數字列
- 一切都是原生的JPA(沒有提供具體自定義類型)
- 容易(和短)的相同類型的新的字段聲明,與其他解決方案
缺點相比:
- 代碼重複(
RegularEnumSet
和PersistentEnumSet
幾乎相同)
- 你可以換的
EnumSet.noneOf(enumType)
結果在PersistenEnumSet
,聲明AccessType.PROPERTY
並提供使用反射兩種接入方式來讀取和寫入elements
場
- 對於應存儲在持久集中的每個枚舉類,需要額外的集合類
- 如果您的持久性提供者支持TS embeddables沒有公共構造函數,你可以添加到
@Embeddable
和PersistentEnumSet
降 額外的類(... interests = new PersistentEnumSet<>(InterestsEnum.class);
)
- 您必須使用
@AttributeOverride
,因爲在我的例子給出的,如果你有一個以上的PersistentEnumSet
在你的實體(否則兩者都將被存儲到同一列「元素」)
values()
與反射在構造函數中的訪問不是最優的(尤其是在查看性能時),但其他兩個選項也有它們的缺點:
- 一個工具像
EnumSet.getUniverse()
通貨膨脹利用的sun.misc
類
- 提供了值數組作爲參數具有風險,即給定值是不正確的參數
- 只有擁有多達64個值枚舉的支持(是真的退稅?)
- 這是不容易的使用條件查詢元素域或JPQL
- 如果你可以用二元運算符或相應的功能位掩碼列,您數據庫支持
如果有人現在閱讀此文件... @CollectionOfElements現在已被棄用,請改爲使用:@ElementCollection – 2010-04-21 16:59:42
您可以在此問題的答案中找到示例:http://stackoverflow.com/q/3152787/363573 – Stephan 2011-08-13 22:24:29
既然你上面提到的Hibernate,我認爲這個答案可能是特定於供應商的,但我不認爲它是這樣的,除非在其他實現中使用JoinTable會導致麻煩。從我所看到的,我相信應該使用CollectionTable。這就是我在我的答案中使用的,它適用於我(儘管是的,我現在也在使用Hibernate)。 – spaaarky21 2012-03-05 20:51:59