Is it possible to write a generic enum converter for JPA?

后端 未结 4 1736
萌比男神i
萌比男神i 2020-12-01 04:51

I wanted to write a Converter for JPA that stores any enum as UPPERCASE. Some enums we encounter do not follow yet the convention to use only Uppercase letters so until they

4条回答
  •  温柔的废话
    2020-12-01 05:11

    Based on @scottb solution I made this, tested against hibernate 4.3: (no hibernate classes, should run on JPA just fine)

    Interface enum must implement:

    public interface PersistableEnum {
        public T getValue();
    }
    

    Base abstract converter:

    @Converter
    public abstract class AbstractEnumConverter & PersistableEnum, E> implements AttributeConverter {
        private final Class clazz;
    
        public AbstractEnumConverter(Class clazz) {
            this.clazz = clazz;
        }
    
        @Override
        public E convertToDatabaseColumn(T attribute) {
            return attribute != null ? attribute.getValue() : null;
        }
    
        @Override
        public T convertToEntityAttribute(E dbData) {
            T[] enums = clazz.getEnumConstants();
    
            for (T e : enums) {
                if (e.getValue().equals(dbData)) {
                    return e;
                }
            }
    
            throw new UnsupportedOperationException();
        }
    }
    

    You must create a converter class for each enum, I find it easier to create static class inside the enum: (jpa/hibernate could just provide the interface for the enum, oh well...)

    public enum IndOrientation implements PersistableEnum {
        LANDSCAPE("L"), PORTRAIT("P");
    
        private final String value;
    
        @Override
        public String getValue() {
            return value;
        }
    
        private IndOrientation(String value) {
            this.value= value;
        }
    
        public static class Converter extends AbstractEnumConverter {
            public Converter() {
                super(IndOrientation.class);
            }
        }
    }
    

    And mapping example with annotation:

    ...
    @Convert(converter = IndOrientation.Converter.class)
    private IndOrientation indOrientation;
    ...
    

    With some changes you can create a IntegerEnum interface and generify for that.

提交回复
热议问题