1.0jpa 2.0
可以使用JPA 2.0保留枚举,但是没有很好的方法来实现。 使用@Enumerated批注,可以使用EnumType.ORDINAL或EnumType.STRING将枚举值映射到其数据库表示形式。 但是这两种选择都有一些缺点,我们将在本文的第一部分中进行讨论。 在第二部分中,我将向您展示通过使用JPA 2.1类型转换器来避免这些缺点。
使用JPA 2.0持久枚举
EnumType.ORDINAL使用Enum.ordinal()的返回值来保留枚举。 因此,枚举的第一个值将被映射为0,第二个将被映射为1,依此类推。 虽然这看起来很紧凑并且易于使用,但是在更改枚举时会引起问题。 删除枚举值或在两者之间的某个位置添加新值将更改以下所有值的映射,例如:
之前:
Vehicle:
CAR -> 0
TRAIN -> 1
PLANE -> 2
后:
Vehicle:
CAR -> 0
BUS -> 1
TRAIN -> 2
PLANE -> 3
在第二个位置添加总线将需要更新数据库以修复枚举映射。
EnumType.STRING看起来是一个更好的选择。 它使用枚举的String表示形式将其持久保存在数据库中。 因此,添加或删除值不会更改映射。 但是这种表示可能非常冗长,重命名枚举值会破坏映射。
之前:
Vehicle:
CAR -> CAR
TRAIN -> TRAIN
PLANE -> PLANE
后:
Vehicle:
CAR -> CAR
BUS -> BUS
TRAIN -> TRAIN
PLANE -> PLANE
使用JPA 2.1类型转换器
JPA 2.1类型转换器提供了第三种,我认为是最佳选择。 类型转换器使我们能够实现将实体属性的值转换为其数据库表示形式并返回的方法。 我不会在如何实现类型转换器方面介绍太多细节,因为在我以前的一篇文章中已经做了。
通过实现我们自己的映射,我们可以选择紧凑的数据库表示形式,并确保以任何方式更改枚举都不会破坏现有的映射。 下面的示例演示如何为Vehicle枚举实现类型转换器:
@Converter(autoApply = true)
public class VehicleConverter implements AttributeConverter<Vehicle, String> {@Overridepublic String convertToDatabaseColumn(Vehicle vehicle) {switch (vehicle) {case BUS:return "B";case CAR:return "C";case PLANE:return "P";case TRAIN:return "T";default:throw new IllegalArgumentException("Unknown value: " + vehicle);}}@Overridepublic Vehicle convertToEntityAttribute(String dbData) {switch (dbData) {case "B":return Vehicle.BUS;case "C":return Vehicle.CAR;case "P":return Vehicle.PLANE;case "T":return Vehicle.TRAIN;default:throw new IllegalArgumentException("Unknown value: " + dbData);}}}
VehicleConverter将枚举值映射到一个字符串。 通过使用@Converter(autoApply = true)进行声明,我们告诉JPA提供程序使用此Type Mapper来映射所有Vehicle枚举。 因此,我们不需要在Vehicle类型的每个实体属性中指定转换器。
但是,我们需要处理一件事,如果您阅读了我以前有关JPA Type Converter的文章,您可能已经想知道了。 类型转换器不能应用于用@Enumerated注释的属性。 因此,我们必须确保在Vehicle类型的实体属性中没有@Enumerated批注。
结论
我们实现了一个简单的类型转换器,该类型转换器使用我们自己的规则将Vehicle枚举转换为其数据库表示形式。 因此,我们可以确保更改Vehicle枚举的值不会破坏现有/剩余的映射。
- 如果您想自己尝试,可以在github上找到源代码: https : //github.com/somethoughtsonjava/JPA2.1-EnumConverter
翻译自: https://www.javacodegeeks.com/2014/05/jpa-2-1-type-converter-the-better-way-to-persist-enums.html
1.0jpa 2.0