Я бы сделал следующее:
Объявите отдельно перечисление в своем собственном файле:
public enum RightEnum {
READ(100), WRITE(200), EDITOR (300);
private int value;
private RightEnum (int value) { this.value = value; }
@Override
public static Etapa valueOf(Integer value){
for( RightEnum r : RightEnum .values() ){
if ( r.getValue().equals(value))
return r;
}
return null;//or throw exception
}
public int getValue() { return value; }
}
Объявить новый объект JPA с именем Right
@Entity
public class Right{
@Id
private Integer id;
//FIElDS
// constructor
public Right(RightEnum rightEnum){
this.id = rightEnum.getValue();
}
public Right getInstance(RightEnum rightEnum){
return new Right(rightEnum);
}
}
Вам также понадобится конвертер для получения этих значений (только JPA 2.1, и есть проблема, которую я не буду обсуждать здесь с этими enum'ами, которые будут напрямую сохраняться с помощью конвертера, так что это будет только односторонняя дорога )
import mypackage.RightEnum;
import javax.persistence.AttributeConverter;
import javax.persistence.Converter;
/**
*
*
*/
@Converter(autoApply = true)
public class RightEnumConverter implements AttributeConverter<RightEnum, Integer>{
@Override //this method shoudn´t be used, but I implemented anyway, just in case
public Integer convertToDatabaseColumn(RightEnum attribute) {
return attribute.getValue();
}
@Override
public RightEnum convertToEntityAttribute(Integer dbData) {
return RightEnum.valueOf(dbData);
}
}
Субъект Органа:
@Entity
@Table(name = "AUTHORITY_")
public class Authority implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "AUTHORITY_ID")
private Long id;
// the **Entity** to map :
private Right right;
// the **Enum** to map (not to be persisted or updated) :
@Column(name="COLUMN1", insertable = false, updatable = false)
@Convert(converter = RightEnumConverter.class)
private RightEnum rightEnum;
}
Поступая таким образом, вы не можете установить непосредственно поле enum. Тем не менее, вы можете установить поле Right в Authority, используя
autorithy.setRight( Right.getInstance( RightEnum.READ ) );//for example
А если вам нужно сравнить, вы можете использовать:
authority.getRight().equals( RightEnum.READ ); //for example
Что довольно круто, я думаю. Это не совсем правильно, так как конвертер не предназначен для использования с enum. На самом деле, в документации сказано, что никогда не используйте его для этой цели, вместо этого вы должны использовать аннотацию @Enumerated. Проблема в том, что существует только два типа enum: ORDINAL или STRING, но ORDINAL сложен и небезопасен.
Однако, если вас это не устраивает, вы можете сделать что-то более хакерское и простое (или нет).
Посмотрим.
The RightEnum:
public enum RightEnum {
READ(100), WRITE(200), EDITOR (300);
private int value;
private RightEnum (int value) {
try {
this.value= value;
final Field field = this.getClass().getSuperclass().getDeclaredField("ordinal");
field.setAccessible(true);
field.set(this, value);
} catch (Exception e) {//or use more multicatch if you use JDK 1.7+
throw new RuntimeException(e);
}
}
@Override
public static Etapa valueOf(Integer value){
for( RightEnum r : RightEnum .values() ){
if ( r.getValue().equals(value))
return r;
}
return null;//or throw exception
}
public int getValue() { return value; }
}
и орган управления
@Entity
@Table(name = "AUTHORITY_")
public class Authority implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "AUTHORITY_ID")
private Long id;
// the **Enum** to map (to be persisted or updated) :
@Column(name="COLUMN1")
@Enumerated(EnumType.ORDINAL)
private RightEnum rightEnum;
}
В этой второй идее, это не идеальная ситуация, поскольку мы взломали порядковый атрибут, но это гораздо меньшая кодировка.
Я думаю, что спецификация JPA должна включать EnumType.ID, где поле значения enum должно быть аннотировано с помощью своего рода аннотации @EnumId.