![](/img/trans.png)
[英]JPA AttributeOverride for Embeddable class with Entity type fields
[英]Enum type fields in JPA Entity
可以在自定義JPA實體中將枚舉用作字段(列)的類型嗎? 這是一個例子:
@Getter @Setter
@Entity
@Table(name = "payments")
public class PaymentEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
@Column(name = "status")
private Integer statusId;
public PaymentStatuses getStatus() {
return PaymentStatuses.valueOf(statusId);
}
public PaymentEntity setStatus(PaymentStatuses status) {
statusId = status == null ? null : status.getId();
return this;
}
}
public enum PaymentStatuses {
CREATED(1),
COMPLETED(2),
CANCELED(3);
private Integer id;
private PaymentStatuses(Integer id) {
this.id = id;
}
public Integer getId() {
return id;
}
public static PaymentStatuses valueOf(Integer id) {
for (PaymentStatuses value : values())
if (value.getId().equals(id))
return value;
return null;
}
}
上面的代碼工作正常,但是使用statusId
和getStatus
setStatus
看起來有點難看。
我想使用PaymentStatuses
作為實體中的字段類型。 像這樣:
@Getter @Setter
@Entity
@Table(name = "payments")
public class PaymentEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
@Column(name = "status")
private PaymentStatuses status;
}
請告訴我,有可能嗎?
使用@Enumerated(EnumType.ORDINAL)
將不起作用,因為ORDINAL
模式開始為0
。
所以枚舉的3個第一值將在DB與表示0
, 1
和2
的值。
而枚舉中表示它在數據庫中的id
字段從1
變為3
:
CREATED(1),
COMPLETED(2),
CANCELED(3);
此外,這種方式可以將枚舉中定義的元素順序與在數據庫中表示元素的方式相關聯。 將來可以添加/刪除枚舉值,這不是一件好事。
解決您的問題的更好方法是定義一個javax.persistence.AttributeConverter
並將其與@Convert
。
因此,創建AttributeConverter
實現以指示如何從DB轉換為枚舉,以及如何將枚舉轉換為DB。
然后在您的實體中聲明PaymentStatuses status
,並通過指定AttributeConverter
實現類用@Convert
進行注釋。
@Getter @Setter
@Entity
@Table(name = "payments")
public class PaymentEntity {
...
@Convert(converter = PaymentStatusesConverter.class)
private PaymentStatuses status;
...
}
public class PaymentStatusesConverter implements AttributeConverter<PaymentStatuses, Integer> {
@Override
public Integer convertToDatabaseColumn(PaymentStatuses status) {
return status.getId();
}
@Override
public PaymentStatuses convertToEntityAttribute(Integer status) {
return PaymentStatuses.valueOf(status);
}
}
是的,但是當您保存到數據庫時,它將保留枚舉值的當前索引(在您的情況下,對於CREATED為0,對於COMPLETED為1,等等),如果您更改枚舉值,則會給您帶來麻煩。 為了避免這種情況,您可以使用@Enumerated
批注,例如:
@Getter @Setter
@Entity
@Table(name = "payments")
public class PaymentEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
@Column(name = "status")
@Enumerated(EnumType.ORDINAL) // There is also EnumType.STRING, or you can define a custom EnumType
private PaymentStatuses status;
}
如果要將數據存儲在數據庫中,例如Java枚舉名稱的名稱( CREATED, COMPLETED, CANCELED
) CREATED, COMPLETED, CANCELED
則可以使用@Enumerated(EnumType.STRING)
)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.