Is it possible to use Enums as a type of a field (column) in custom JPA entities? Here is an example:
@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;
}
}
Code above works fine, but approach with statusId and getStatus setStatus looks ugly a little bit.
I wanna use PaymentStatuses as a type of the field in my entity. Like this:
@Getter @Setter
@Entity
@Table(name = "payments")
public class PaymentEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
@Column(name = "status")
private PaymentStatuses status;
}
Tell me please, is it possible?
Using @Enumerated(EnumType.ORDINAL) will not work because the ORDINAL mode starts to 0.
So the 3 first values of the enum will be represented in DB with the 0, 1 and 2 values.
while the id field in the enum to represent it in the DB goes from 1 to 3 :
CREATED(1),
COMPLETED(2),
CANCELED(3);
Besides, this way would correlate the order of elements defined in the enum with the way to represent them in database. Which not a good thing as enum values could be added/removed in the future.
A better way to address your issue is defining a javax.persistence.AttributeConverter and using it with @Convert.
So create a AttributeConverter implementation to indicate how to convert from the DB to the enum and the enum to the DB.
Then declare a PaymentStatuses status in your entity and annotate it with @Convert by specifying the AttributeConverter implementation class.
@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);
}
}
Yes, but when you save to the database it will persist the current index of the enum value (in your case 0 for CREATED, 1 for COMPLETED, etc.) which will give you trouble if you change the enum values. To avoid this you can use the @Enumerated annotation like:
@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;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With