Registering Converters in JPA 2.1 with EclipseLink

前端 未结 4 1754
醉酒成梦
醉酒成梦 2021-02-06 16:00

On JavaEE environment, I use JPA 2.1 implementation with EclipseLink,

I have some entities that contain enums. So I have created converters for these enume

相关标签:
4条回答
  • 2021-02-06 16:41

    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

    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>
    
    0 讨论(0)
  • 2021-02-06 16:44

    My guess is that you have intermixed javax.persistence and org.eclipse.persistence.annotations packages.

    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.

    0 讨论(0)
  • 2021-02-06 16:56

    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.

    Also note that as mentioned above, if you start to add a single class in the persistence.xml you have to add everything.

    0 讨论(0)
  • 2021-02-06 16:59

    Wait till they release the patch for your application server.

    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

    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

    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:

    @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);
    }
    
    0 讨论(0)
提交回复
热议问题