Java 使用EclipseLink在JPA2.1中注册转换器

Java 使用EclipseLink在JPA2.1中注册转换器,java,jakarta-ee,jpa,eclipselink,jpa-2.1,Java,Jakarta Ee,Jpa,Eclipselink,Jpa 2.1,在JavaEE环境中,我使用带有EclipseLink的JPA2.1实现 我有一些实体包含枚举。所以我为这些枚举创建了转换器 汽车实体: @Entity public class Car implements Serializable { private static final long serialVersionUID = 6L; @Id private String id; @Convert (converter = CarColorConv

在JavaEE环境中,我使用带有EclipseLink的JPA2.1实现

我有一些实体包含
枚举
。所以我为这些枚举创建了转换器

汽车实体:

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

    ....
}
@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);
        }
    }
}
CarColor转换器:

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

    ....
}
@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);
        }
    }
}
@Converter(converterClass=CarColorConverter.class,name=“CarColorConverter”)
公共类CarColorConverter实现AttributeConverter{
私有静态最终字符串BLACK=“BLACK”;
私有静态最终字符串GRAY=“GRAY”;
私有静态最终字符串WHITE=“WHITE”;
私有静态最终字符串RED=“RED”;
@凌驾
公共字符串convertToDatabaseColumn(CarColor entityData){
交换机(entityData){
黑色外壳:
返回黑色;
灰色案例:
返回灰色;
白色外壳:
返回白色;
红色表壳:
返回红色;
违约:
抛出新的IllegalArgumentException(“未知:+entityData”);
}
}
@凌驾
公共CarColor convertToEntityAttribute(字符串dbData){
交换机(dbData){
黑色外壳:
返回颜色。黑色;
灰色案例:
返回颜色。灰色;
白色外壳:
返回颜色。白色;
红色表壳:
返回颜色:红色;
违约:
抛出新的IllegalArgumentException(“未知:+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>

com.xtz.model.Car
...
  • 我在persistence.xml文件上注释转换器的声明,并尝试在数据库中持久化我的实体时,我收到以下错误:“请确保转换器类名正确,并且与持久化单元定义一起存在。”。没有编译时异常,只有一个非常明确的警告:

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

  • 但是,当我取消注释persistence.xml文件上的转换器声明,并尝试在数据库中持久化我的实体时,我会收到以下错误:“请确保转换器类名正确,并且与持久化单元定义一起存在。”。和编译时异常:

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

  • 我是否以错误的方式申报转换器


    谢谢。

    我猜您混合了
    javax.persistence
    org.eclipse.persistence.annotations


    使用
    javax.persistence
    包类,可以在转换器类上使用空的
    Converter
    注释,在实体类上使用指定转换器类的
    Convert
    注释。

    尝试一下,确保包含了正确的包

    汽车实体 保持不变

    import javax.persistence.Convert;
    
    @Entity
    public class Car implements Serializable {
    
        [...]
    
        @Convert(converter = CarColorConverter.class)
        private CarColor    color;
    
        [...]
    }
    
    汽车颜色转换器 您只需要空注释

    import javax.persistence.AttributeConverter;
    import javax.persistence.Converter;
    
    @Converter
    public class CarColorConverter implements AttributeConverter<CarColor, String> {
        [...]
    }
    
    import javax.persistence.AttributeConverter;
    导入javax.persistence.Converter;
    @转换器
    公共类CarColorConverter实现AttributeConverter{
    [...]
    }
    
    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>
    
            [...]
        </persistence-unit>
    </persistence>
    
    
    com.xyz.model.converters.CarColorConverter
    com.xtz.model.Car
    [...]
    
    只是想说一句话,空的
    @Converter
    注释是通过EclipseLink从JPA2.1开始支持的。您可以在project(右键单击)->properties->facets下找到使用过的JPA版本


    另外请注意,如上所述,如果您开始在
    persistence.xml
    中添加单个类,则必须添加所有内容。

    等待他们发布应用程序服务器的修补程序

    中列出了挂起的发布计划

    现在的解决方法是将其存储为
    字符串
    ,并有一个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() {
    
        }
    }
    

    顺便说一句,有一个带有enumType String或Ordinal的@Enumerated注释。。。