java 使用 EclipseLink 在 JPA 2.1 中注册转换器
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/27574855/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Registering Converters in JPA 2.1 with EclipseLink
提问by thomas.mc.work
On JavaEE environment, I use JPA 2.1 implementation with EclipseLink,
在 JavaEE 环境中,我使用带有 EclipseLink 的 JPA 2.1 实现,
I have some entities that contain enums
. So I have created converters for these enumerations.
我有一些包含enums
. 所以我为这些枚举创建了转换器。
Car entity :
汽车实体:
@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<CarColor, String> {
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
持久化文件
<?xml version="1.0" encoding="UTF-8"?>
<persistence
version="2.1"
xmlns="http://xmlns.jcp.org/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd">
<persistence-unit name="xyz-restful-api" transaction-type="RESOURCE_LOCAL">
<!-- Converters -->
<!--<class>com.xyz.model.converters.CarColorConverter</class>-->
<!-- Entities / Model -->
<class>com.xtz.model.Car</class>
<properties>
...
</properties>
</persistence-unit>
</persistence>
When I commentthe declaration of the converter on the persistence.xml file, and try to persist my entities in the DB I get this error : "Please ensure the converter class name is correct and exists with the persistence unit definition.". and no compilation time exception, only a warning pretty explicit :
Class "com.xyz.model.converters.CarTypeConverter" is annotated, but not listed in the persistence.xml file
However, when I uncommentthe declaration of the converter on the on the persistence.xml file, and try to persist my entities in the DB I get this error : "Please ensure the converter class name is correct and exists with the persistence unit definition.". and a compilation time exception :
Class "com.xyz.model.converters.CarColorConverter" is listed in the persistence.xml file, but is not annotated
当我在persistence.xml 文件上评论转换器的声明,并尝试将我的实体持久保存在数据库中时,我收到此错误:“请确保转换器类名称正确并且与持久性单元定义一起存在。”。并且没有编译时异常,只有一个非常明确的警告:
类“com.xyz.model.converters.CarTypeConverter”有注释,但未在persistence.xml文件中列出
但是,当我取消对persistence.xml 文件上的转换器声明的注释,并尝试将我的实体保留在数据库中时,我收到此错误:“请确保转换器类名称正确并且存在于持久性单元定义中。”。和编译时异常:
类“com.xyz.model.converters.CarColorConverter”列在persistence.xml文件中,但没有注释
Am I declaring the converters in a wrong way ?
我是否以错误的方式声明转换器?
Thank you.
谢谢你。
回答by thomas.mc.work
Give this a try and ensure you have included the correct packages.
试一试并确保您包含了正确的包。
Car entity
汽车实体
Stays the same
保持不变
import javax.persistence.Convert;
@Entity
public class Car implements Serializable {
[...]
@Convert(converter = CarColorConverter.class)
private CarColor color;
[...]
}
CarColor Converter
汽车颜色转换器
You only need the empty Annotation
你只需要空的 Annotation
import javax.persistence.AttributeConverter;
import javax.persistence.Converter;
@Converter
public class CarColorConverter implements AttributeConverter<CarColor, String> {
[...]
}
persistence.xml
持久化文件
You can either
你可以要么
- declare no class at all
- 根本不声明任何类
or
或者
- declare every class that is involved.
- 声明涉及的每个类。
As soon as you need to declare an entity manually (e.g. when it resists in a library) then you also need do declare all other entity/converter classes.
一旦您需要手动声明实体(例如,当它在库中抵抗时),那么您还需要声明所有其他实体/转换器类。
<?xml version="1.0" encoding="UTF-8"?>
<persistence
version="2.1"
xmlns="http://xmlns.jcp.org/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd">
<persistence-unit name="xyz-restful-api" transaction-type="RESOURCE_LOCAL">
<!-- Converters -->
<class>com.xyz.model.converters.CarColorConverter</class>
<!-- Entities / Model -->
<class>com.xtz.model.Car</class>
[...]
</persistence-unit>
</persistence>
回答by Petros Splinakis
My guess is that you have intermixed javax.persistence
and org.eclipse.persistence.annotations
packages.
我的猜测是你混合了javax.persistence
和org.eclipse.persistence.annotations
包。
Using javax.persistence
package classes, you may use an empty Converter
annotation on the converter class and a Convert
annotation on the entity class specifying the converter class.
使用javax.persistence
包类,您可以Converter
在转换器类上使用空Convert
注释,在实体类上使用指定转换器类的注释。
回答by Frank Essenberger
Just wanted to make the small remark, that the empty @Converter
annotation is supported from JPA 2.1 up via EclipseLink 1. You find the used JPA version under project(rightclick)->properties->facets.
只是想说一下,@Converter
从 JPA 2.1 开始,通过 EclipseLink 1支持空注释。您可以在项目(右键单击)-> 属性-> 构面下找到使用的 JPA 版本。
Also note that as mentioned above, if you start to add a single class in the persistence.xml
you have to add everything.
另请注意,如上所述,如果您开始在 中添加单个类,则persistence.xml
必须添加所有内容。
回答by Archimedes Trajano
Wait till they release the patch for your application server.
等到他们为您的应用程序服务器发布补丁。
https://bugs.eclipse.org/bugs/show_bug.cgi?id=443546
https://bugs.eclipse.org/bugs/show_bug.cgi?id=443546
The release schedules pending are listed in http://www-01.ibm.com/support/docview.wss?uid=swg27004980
http://www-01.ibm.com/support/docview.wss?uid=swg27004980中列出了待定的发布时间表
The workaround for now is to store it as a String
and have a getter and setter that would do the transform for you like this
现在的解决方法是将其存储为 aString
并有一个 getter 和 setter 可以像这样为您进行转换
public final class StaticEnumToStringConverter {
public static <E extends Enum<E>> String convertToDatabaseColumn(final E attribute) {
if (attribute == null) {
return null;
}
return attribute.toString();
}
public static <E extends Enum<E>> E convertToEntityAttribute(final String dbData, final Class<E> 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() {
}
}
Then use in the JPA Entity as:
然后在 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);
}