有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

JPA实体中的java枚举类型字段

是否可以在自定义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{}的方法看起来有点难看

我想在我的实体中使用PaymentStatuses作为字段的一种类型。像这样:

@Getter @Setter
@Entity
@Table(name = "payments")
public class PaymentEntity {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;

    @Column(name = "status")
    private PaymentStatuses status;
}

请告诉我,可能吗


共 (1) 个答案

  1. # 1 楼答案

    使用@Enumerated(EnumType.ORDINAL)将不起作用,因为ORDINAL模式开始0
    因此,枚举的前3个值将用012值以DB表示
    而在数据库中表示它的枚举中的id字段从13

    CREATED(1),
    COMPLETED(2),
    CANCELED(3);
    

    此外,这种方式将把枚举中定义的元素的顺序与在数据库中表示它们的方式关联起来。这不是一件好事,因为将来可以添加/删除枚举值

    解决问题的更好方法是定义一个^{},并将其与^{}一起使用
    因此,创建一个AttributeConverter实现来指示如何从DB转换到enum,以及如何将enum转换到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); 
        }
    }