我正在寻找使用JPA映射枚举的不同方法。我特别想设置每个枚举条目的整数值,并且只保存整数值。
@Entity
@Table(name = "AUTHORITY_")
public class Authority implements Serializable {
public enum Right {
READ(100), WRITE(200), EDITOR (300);
private int value;
Right(int value) { this.value = value; }
public int getValue() { return value; }
};
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "AUTHORITY_ID")
private Long id;
// the enum to map :
private Right right;
}
一个简单的解决方案是将枚举注释与EnumType.ORDINAL一起使用:
@Column(name = "RIGHT")
@Enumerated(EnumType.ORDINAL)
private Right right;
但在本例中,JPA映射的是枚举索引(0,1,2),而不是我想要的值(100,200,300)。
我发现的这两个解决方案看起来并不简单。
第一个解决方案
解决方案proposed here使用@PrePersist和@PostLoad将枚举转换为其他字段,并将枚举字段标记为临时字段:
@Basic
private int intValueForAnEnum;
@PrePersist
void populateDBFields() {
intValueForAnEnum = right.getValue();
}
@PostLoad
void populateTransientFields() {
right = Right.valueOf(intValueForAnEnum);
}
第二种解决方案
第二个解决方案proposed here提出了一个通用的转换对象,但看起来仍然是笨重的和面向hibernate的(@Type似乎不存在于Java中):
@Type(
type = "org.appfuse.tutorial.commons.hibernate.GenericEnumUserType",
parameters = {
@Parameter(
name = "enumClass",
value = "Authority$Right"),
@Parameter(
name = "identifierMethod",
value = "toInt"),
@Parameter(
name = "valueOfMethod",
value = "fromInt")
}
)
有没有其他的解决方案?
我有几个想法,但我不知道它们是否存在于JPA中:
发布于 2010-05-02 07:25:57
对于早于JPA2.1的版本,JPA只提供了两种方法来处理枚举,通过它们的name
或者通过它们的ordinal
。并且标准JPA不支持自定义类型。所以:
UserType
,EclipseLink Converter
等)。(第二种解决方案)。~或者~int
值~或~我将演示最新的选项(这是一个基本的实现,根据需要进行调整):
@Entity
@Table(name = "AUTHORITY_")
public class Authority implements Serializable {
public enum Right {
READ(100), WRITE(200), EDITOR (300);
private int value;
Right(int value) { this.value = value; }
public int getValue() { return value; }
public static Right parse(int id) {
Right right = null; // Default
for (Right item : Right.values()) {
if (item.getValue()==id) {
right = item;
break;
}
}
return right;
}
};
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "AUTHORITY_ID")
private Long id;
@Column(name = "RIGHT_ID")
private int rightId;
public Right getRight () {
return Right.parse(this.rightId);
}
public void setRight(Right right) {
this.rightId = right.getValue();
}
}
发布于 2014-01-12 17:52:57
现在使用JPA 2.1可以做到这一点:
@Column(name = "RIGHT")
@Enumerated(EnumType.STRING)
private Right right;
更多详细信息:
发布于 2014-08-11 23:32:57
在JPA2.1中,您可以使用AttributeConverter。
创建一个枚举类,如下所示:
public enum NodeType {
ROOT("root-node"),
BRANCH("branch-node"),
LEAF("leaf-node");
private final String code;
private NodeType(String code) {
this.code = code;
}
public String getCode() {
return code;
}
}
创建一个转换器,如下所示:
import javax.persistence.AttributeConverter;
import javax.persistence.Converter;
@Converter(autoApply = true)
public class NodeTypeConverter implements AttributeConverter<NodeType, String> {
@Override
public String convertToDatabaseColumn(NodeType nodeType) {
return nodeType.getCode();
}
@Override
public NodeType convertToEntityAttribute(String dbData) {
for (NodeType nodeType : NodeType.values()) {
if (nodeType.getCode().equals(dbData)) {
return nodeType;
}
}
throw new IllegalArgumentException("Unknown database value:" + dbData);
}
}
在您只需要的实体上:
@Column(name = "node_type_code")
您使用@Converter(autoApply = true)
的运气可能因容器而异,但经过测试可以在Wildfly 8.1.0上运行。如果它不起作用,您可以在实体类列中添加@Convert(converter = NodeTypeConverter.class)
。
https://stackoverflow.com/questions/2751733
复制相似问题