簡體   English   中英

JPA實體中的枚舉類型字段

[英]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;
    }
}

上面的代碼工作正常,但是使用statusIdgetStatus 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與表示012的值。
而枚舉中表示它在數據庫中的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, CANCELEDCREATED, COMPLETED, CANCELED則可以使用@Enumerated(EnumType.STRING) )。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM