Registrando conversores no JPA 2.1 com o EclipseLink

No ambiente JavaEE, eu uso a implementação do JPA 2.1 com o EclipseLink,

Eu tenho algumas entidades que contêm enums . Então eu criei conversores para essas enumerações.

Entidade do carro:

 @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:

 @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. Quando eu comento a declaração do conversor no arquivo persistence.xml e tento persistir minhas entidades no database, recebo este erro: ” Por favor, assegure-se de que o nome da class do conversor esteja correto e exista com a definição da unidade de persistência. ” e nenhuma exceção de tempo de compilation, apenas um aviso bem explícito:

    A class “com.xyz.model.converters.CarTypeConverter” é anotada, mas não está listada no arquivo persistence.xml

  2. No entanto, quando descomentei a declaração do conversor no arquivo persistence.xml e tentei persistir minhas entidades no database, recebi este erro: ” Certifique-se de que o nome da class do conversor esteja correto e exista com a definição da unidade de persistência. “. e uma exceção de tempo de compilation:

    A class “com.xyz.model.converters.CarColorConverter” está listada no arquivo persistence.xml, mas não é anotada

Estou declarando os conversores de maneira errada?

Obrigado.

Experimente e certifique-se de ter incluído os pacotes corretos.

Entidade automóvel

Continua o mesmo

 import javax.persistence.Convert; @Entity public class Car implements Serializable { [...] @Convert(converter = CarColorConverter.class) private CarColor color; [...] } 

Conversor CarColor

Você só precisa da anotação vazia

 import javax.persistence.AttributeConverter; import javax.persistence.Converter; @Converter public class CarColorConverter implements AttributeConverter { [...] } 

persistence.xml

Você pode

  • não declarar nenhuma class

ou

  • declarar todas as classs envolvidas.

Assim que você precisar declarar uma entidade manualmente (por exemplo, quando ela resiste em uma biblioteca), você também precisará declarar todas as outras classs de entidade / conversor.

     com.xyz.model.converters.CarColorConverter  com.xtz.model.Car [...]   

Só queria fazer a pequena observação, que a anotação vazia do @Converter é suportada pelo JPA 2.1 através do EclipseLink 1 . Você encontra a versão do JPA usada no projeto (rightclick) -> properties-> facets.

Observe também que, como mencionado acima, se você começar a adicionar uma única class no persistence.xml será necessário adicionar tudo.

Meu palpite é que você javax.persistence pacotes javax.persistence e org.eclipse.persistence.annotations .

Usando javax.persistence classs do pacote javax.persistence , você pode usar uma anotação Converter vazia na class do conversor e uma anotação Convert na class de entidade que especifica a class do conversor.

Espere até que eles liberem o patch para o seu servidor de aplicativos.

https://bugs.eclipse.org/bugs/show_bug.cgi?id=443546

Os planejamentos de liberação pendentes estão listados em http://www-01.ibm.com/support/docview.wss?uid=swg27004980

A solução para agora é armazená-lo como uma String e ter um getter e setter que faria a transformação para você assim

 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() { } } 

Em seguida, use na Entidade JPA como:

 @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); }