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

后端 未结 4 1740
萌比男神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:19

    The above solutions are really fine. My small additions here.

    I also added the following to enforce when implementing the interface writing a converter class. When you forget jpa starts using default mechanisms which are really fuzzy solutions (especially when mapping to some number value, which I always do).

    The interface class looks like this:

    public interface PersistedEnum & PersistedEnum> {
      int getCode();
      Class> getConverterClass();
    }
    

    With the PersistedEnumConverter similar to previous posts. However when the implementing this interface you have to deal with the getConverterClass implementation, which is, besides being an enforcement to provide the specific converter class, completely useless.

    Here is an example implementation:

    public enum Status implements PersistedEnum {
      ...
    
      @javax.persistence.Converter(autoApply = true)
      static class Converter extends PersistedEnumConverter {
          public Converter() {
              super(Status.class);
          }
      }
    
      @Override
      public Class> getConverterClass() {
          return Converter.class;
      }
    
      ...
    }
    

    And what I do in the database is always make a companion table per enum with a row per enum value

     create table e_status
        (
           id    int
               constraint pk_status primary key,
           label varchar(100)
        );
    
      insert into e_status
      values (0, 'Status1');
      insert into e_status
      values (1, 'Status2');
      insert into e_status
      values (5, 'Status3');
    

    and put a fk constraint from wherever the enum type is used. Like this the usage of correct enum values is always guaranteed. I especially put values 0, 1 and 5 here to show how flexible it is, and still solid.

    create table using_table
       (
            ...
        status         int          not null
            constraint using_table_status_fk references e_status,
            ...
       );
    

提交回复
热议问题