使用EclipseLink在JPA 2.1中注册转换器
在JavaEE环境中,我使用EclipseLink的JPA 2.1实现,
我有一些包含enums
实体。 所以我为这些枚举创建了转换器。
汽车实体:
@Entity public class Car implements Serializable { private static final long serialVersionUID = 6L; @Id private String id; @Convert (converter = CarColorConverter.class) private CarColor color; public enum CarColor { Black, Gray, White, Red }; public Car () { id = GenerateUUID.id (); } .... }
CarColor转换器:
@Converter (converterClass = CarColorConverter.class, name = "CarColorConverter") public class CarColorConverter implements AttributeConverter { private static final String BLACK = "Black"; private static final String GRAY = "Gray"; private static final String WHITE = "White"; private static final String RED = "Red"; @Override public String convertToDatabaseColumn (CarColor entityData) { switch (entityData) { case Black: return BLACK; case Gray: return GRAY; case White: return WHITE; case Red: return RED; default: throw new IllegalArgumentException ("Unknown : " + entityData); } } @Override public CarColor convertToEntityAttribute (String dbData) { switch (dbData) { case BLACK: return CarColor.Black; case GRAY: return CarColor.Gray; case WHITE: return CarColor.White; case RED: return CarColor.Red; default: throw new IllegalArgumentException ("Unknown : " + dbData); } } }
persistence.xml中
<!--com.xyz.model.converters.CarColorConverter--> com.xtz.model.Car ...
-
当我在persistence.xml文件上注释转换器的声明,并尝试在DB中保留我的实体时,我收到此错误:“ 请确保转换器类名称正确并且存在持久性单元定义。 ”。 并且没有编译时exception,只有一个非常明确的警告:
类“com.xyz.model.converters.CarTypeConverter”已注释,但未在persistence.xml文件中列出
-
但是,当我取消注释 persistence.xml文件上的转换器声明,并尝试在DB中保留我的实体时,我收到此错误:“ 请确保转换器类名称正确并且存在持久性单元定义。 ”。 和编译时间exception:
类“com.xyz.model.converters.CarColorConverter”列在persistence.xml文件中,但未注释
我是以错误的方式宣布转换器吗?
谢谢。
尝试一下,确保包含正确的包。
汽车实体
保持不变
import javax.persistence.Convert; @Entity public class Car implements Serializable { [...] @Convert(converter = CarColorConverter.class) private CarColor color; [...] }
CarColor转换器
您只需要空注释
import javax.persistence.AttributeConverter; import javax.persistence.Converter; @Converter public class CarColorConverter implements AttributeConverter { [...] }
persistence.xml中
你也可以
- 根本没有宣布任何课程
要么
- 声明所涉及的每个类。
只要您需要手动声明实体(例如,当它在库中存在时),您还需要声明所有其他实体/转换器类。
com.xyz.model.converters.CarColorConverter com.xtz.model.Car [...]
只是想做一个小小的评论,从JPA 2.1到EclipseLink 1支持空的@Converter
注释。 您可以在项目(右键单击) – > properties-> facets下找到使用过的JPA版本。
另请注意,如上所述,如果您开始在persistence.xml
添加单个类,则必须添加所有内容。
我的猜测是你混合了javax.persistence
和org.eclipse.persistence.annotations
包。
使用javax.persistence
包类,您可以在转换器类上使用空的Converter
注释,并在实体类上使用Convert
annotation指定转换器类。
等到他们发布应用服务器的补丁。
https://bugs.eclipse.org/bugs/show_bug.cgi?id=443546
挂起的发布计划列于http://www-01.ibm.com/support/docview.wss?uid=swg27004980
现在的解决方法是将它存储为一个String
并有一个getter和setter,可以像这样对你进行转换
public final class StaticEnumToStringConverter { public static > String convertToDatabaseColumn(final E attribute) { if (attribute == null) { return null; } return attribute.toString(); } public static > E convertToEntityAttribute(final String dbData, final Class enumClass) { if (dbData == null) { return null; } for (final E c : EnumSet.allOf(enumClass)) { if (dbData.equals(c.toString())) { return c; } } throw new IllegalArgumentException(dbData); } private StaticEnumToStringConverter() { } }
然后在JPA实体中使用:
@NotNull @Column(nullable = false) private String genderAtBirth; public Gender getGenderAtBirth() { return StaticEnumToStringConverter.convertToEntityAttribute(genderAtBirth, Gender.class); } public void setGenderAtBirth(final Gender genderAtBirth) { this.genderAtBirth = StaticEnumToStringConverter.convertToDatabaseColumn(genderAtBirth); }