使用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  ...    
  1. 在persistence.xml文件上注释转换器的声明,并尝试在DB中保留我的实体时,我收到此错误:“ 请确保转换器类名称正确并且存在持久性单元定义。 ”。 并且没有编译时exception,只有一个非常明确的警告:

    类“com.xyz.model.converters.CarTypeConverter”已注释,但未在persistence.xml文件中列出

  2. 但是,当我取消注释 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.persistenceorg.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); }