There's a Microservice I'm working on, that used to have one kind of Enum related to one of it's columns, but now I had to change it.
@Convert(converter = TypeEnumConverter.class)
@Enumerated(EnumType.STRING)
@Column(name = "TIPO", length = 40, nullable = false)
private TypeEnum type;
It's mapped like that, but the enums names and types are imcompatible, is there a way to tell JPA to ignore it if it can't transform back to that enum?
You can implement a custom enum mapping using an AttributeConverter. Within the converter, you could then map unknown enum values to null. But please be aware that the next update operation would then remove the value from that database column.
You already reference your TypeEnumConverter attribute converter in the @Convert annotation in your mapping. If you want to use it, you need to remove the @Enumerated annotation. The JPA specification doesn't allow you to use these 2 annotations together because both define how the Enum values get mapped.
Here is an example of how such a mapping could look like.
I use this simple Vehicle enum:
public enum Vehicle {
BUS, CAR, TRAIN, PLANE;
}
The attribute converter implements the mapping between the Java object and the value stored in your database. It's a simple Java class that implements the AttributeConverter interface and is annotated with @Converter. If you set the autoApply attribute to true, it will be automatically used for all entity attributes of the converted type.
@Converter(autoApply = true)
public class VehicleConverter implements AttributeConverter<Vehicle, String> {
@Override
public String convertToDatabaseColumn(Vehicle vehicle) {
switch (vehicle) {
case Vehicle.BUS:
return "B";
case Vehicle.CAR:
return "C";
case Vehicle.TRAIN:
return "T";
case Vehicle.PLANE:
return "P";
}
}
@Override
public Vehicle convertToEntityAttribute(String dbData) {
switch (dbData) {
case "B":
return Vehicle.BUS;
case "C":
return Vehicle.CAR;
case "T":
return Vehicle.TRAIN;
case "P":
return Vehicle.PLANE;
default:
// ignore unknown values
return null;
}
}
}
You can then use the enum without any additional mapping annotations in your entity class.
@Entity
public class Trip {
private Vehicle vehicle;
...
}
If you don't mind losing the legacy values in the DB that are incompatible with the current Enum then @Thorben response is the way to go.
If you want to preserve them, then one solution would be to declare your field as a String, and provide accessory methods to manipulate the value as an enum. Something like:
@Column(name = "TIPO", length = 40, nullable = false)
private String type;
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public TypeEnum getTypeEnum() {
try {
return TypeEnum.valueOf(type);
} catch (IllegalArgumentException e) {
return null;
}
}
public void setTypeEnum(TypeEnum typeEnum) {
if (typeEnum != null) {
type = typeEnum.toString();
}
}
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