在JPA中有一种方法可以在Entity类中映射枚举的集合吗?或者唯一的解决方案是使用另一个域类包装Enum并使用它来映射集合?
@Entity
public class Person {
public enum InterestsEnum {Books, Sport, etc... }
//@???
Collection<InterestsEnum> interests;
}
Run Code Online (Sandbox Code Playgroud)
我正在使用Hibernate JPA实现,但当然更喜欢实现不可知的解决方案.
小智 108
使用Hibernate你可以做到
@CollectionOfElements(targetElement = InterestsEnum.class)
@JoinTable(name = "tblInterests", joinColumns = @JoinColumn(name = "personID"))
@Column(name = "interest", nullable = false)
@Enumerated(EnumType.STRING)
Collection<InterestsEnum> interests;
Run Code Online (Sandbox Code Playgroud)
spa*_*y21 60
Andy的答案中的链接是在JPA 2中映射"非实体"对象集合的一个很好的起点,但在映射枚举时并不完全.这是我想出来的.
@Entity
public class Person {
@ElementCollection(targetClass=InterestsEnum.class)
@Enumerated(EnumType.STRING) // Possibly optional (I'm not sure) but defaults to ORDINAL.
@CollectionTable(name="person_interest")
@Column(name="interest") // Column name in person_interest
Collection<InterestsEnum> interests;
}
Run Code Online (Sandbox Code Playgroud)
我能够通过以下简单方式完成此任务:
@ElementCollection(fetch = FetchType.EAGER)
Collection<InterestsEnum> interests;
Run Code Online (Sandbox Code Playgroud)
预先加载需要,以避免延迟加载inizializing错误的解释在这里。
tl;dr 一个简短的解决方案如下:
@ElementCollection(targetClass = InterestsEnum.class)
@CollectionTable
@Enumerated(EnumType.STRING)
Collection<InterestsEnum> interests;
Run Code Online (Sandbox Code Playgroud)
长的答案是,使用此注释,JPA 将创建一个表,该表将保存指向主类标识符(在本例中为 Person.class)的 InterestsEnum 列表。
@ElementCollections 指定 JPA 可以在何处找到有关 Enum 的信息
@CollectionTable 创建保存从 Person 到 InterestsEnum 的关系的表
@Enumerated(EnumType.STRING) 告诉 JPA 将枚举作为字符串持久化,可以是 EnumType.ORDINAL
我使用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
// ...
}
Run Code Online (Sandbox Code Playgroud)
此类现在是我所有枚举集的基础:
@Embeddable
public class InterestsSet extends PersistentEnumSet<InterestsEnum> {
public InterestsSet() {
super(InterestsEnum.class);
}
}
Run Code Online (Sandbox Code Playgroud)
我可以在我的实体中使用的那个集:
@Entity
public class MyEntity {
// ...
@Embedded
@AttributeOverride(name="elements", column=@Column(name="interests"))
private InterestsSet interests = new InterestsSet();
}
Run Code Online (Sandbox Code Playgroud)
好处:
java.util.EnumSet
获取描述)缺点:
RegularEnumSet
和PersistentEnumSet
几乎相同)
EnumSet.noneOf(enumType)
中PersistenEnumSet
,声明AccessType.PROPERTY
并提供两种访问方法,这些方法使用反射来读取和写入elements
字段@Embeddable
到PersistentEnumSet
并删除多余的类(... interests = new PersistentEnumSet<>(InterestsEnum.class);
)@AttributeOverride
如果您PersistentEnumSet
的实体中有多个实体,则必须使用如我的示例中给出的,否则两者都将存储在同一列“元素”中)values()
在构造函数中使用with反射的访问不是最佳的(特别是在查看性能时),但是其他两个选项也有其缺点:
EnumSet.getUniverse()
实现利用了一个sun.misc
类 归档时间: |
|
查看次数: |
59764 次 |
最近记录: |