【问题标题】:Can I use one Enum as DiscriminatorType and Column in parent class?我可以在父类中使用一个 Enum 作为 DiscriminatorType 和 Column 吗?
【发布时间】:2021-04-24 10:22:44
【问题描述】:

我正在创建具有不同维修类型的维修服务。我有一个 SINGLE_TABLE 继承,我用 Enum repair_Type 区分它们,我还希望将 Repair_Type 作为一列,这样我就可以按类型对修复进行排序和搜索,但我得到了No enum constant 异常。

这是我的代码:

@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(discriminatorType = DiscriminatorType.STRING)
public abstract class Repair {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    public long repairID;

    @ManyToOne
    private Customer customerID;

    @Enumerated(EnumType.STRING)
    private RepairType repairType;

    @OneToMany
    private List<Employee> employeeList;

    @Enumerated(EnumType.STRING)
    private DeliveryOption deliveryOption;

    private boolean expressRepair;

    private boolean cleanProduct;

    @Column(length = 64)
    private String productImage;

    @OneToOne
    private Brand brand;

    private String model;

    private int size;

    private int buildYear;

    @Temporal(TemporalType.TIMESTAMP)
    private Date dateCreated;

    @Column(nullable = false)
    private String repairNote;
}
No getters and setters for brevity

修复类型:

public enum RepairType {
    KITE(Types.KITE),
    BOARD(Types.BOARD),
    BAR(Types.BAR),
    WETSUIT(Types.WETSUIT);

    private String type;

    RepairType(String type) {
    }

    public static class Types {
        public static final String KITE = "Kite";
        public static final String BOARD = "Board";
        public static final String BAR = "Bar";
        public static final String WETSUIT = "Wetsuit";
    }
}

子类修复类型示例(我有四个)

@Entity
@DiscriminatorValue(value = RepairType.Types.BAR)
public class BarRepair extends Repair {

    private boolean lengthCheck;

    public BarRepair() {
    }

    public BarRepair(long repairID, Customer customerID, List<Employee> employeeList, DeliveryOption deliveryOption, boolean expressRepair, boolean cleanProduct, String productImage, Brand brand, String model, int size, int buildYear, Date dateCreated, String repairNote, boolean lengthCheck) {
        super(repairID, customerID, employeeList, deliveryOption, expressRepair, cleanProduct, productImage, brand, model, size, buildYear, dateCreated, repairNote);
        this.lengthCheck = lengthCheck;
    }

    public boolean isLengthCheck() {
        return lengthCheck;
    }

    public void setLengthCheck(boolean lengthCheck) {
        this.lengthCheck = lengthCheck;
    }
}

【问题讨论】:

    标签: java spring-boot hibernate jpa enums


    【解决方案1】:

    使用@Enumerated(EnumType.STRING) 映射的枚举使用枚举的.name() 表示进行映射。所以在你的情况下:KITEBOARD,...

    由于您将它们保存为KiteBoard 等,Hibernate ORM 无法找到每个 String 值的枚举。

    我认为您需要使用@AttributeConverter

    @Converter
    public static class RepairTypeConverter
            implements AttributeConverter<RepairType, String> {
    
        public Character convertToDatabaseColumn( RepairType value ) {
            if ( value == null ) {
                return null;
            }
    
            return value.getType();
        }
    
        public RepairType convertToEntityAttribute( String value ) {
            if ( value == null ) {
                return null;
            }
    
            return RepairType.fromType( value );
        }
    }
    

    其中getType()fromType() 用于将枚举转换为类型,反之亦然。

    然后您可以使用以下方式映射属性:

    @Entity
    @Inheritance(strategy = InheritanceType.SINGLE_TABLE)
    @DiscriminatorColumn(name="repair_Type", discriminatorType = DiscriminatorType.STRING)
    public abstract class Repair {
        ...
        
        @Convert( converter = RepairTypeConverter.class )
        @Column(name = "repair_Type)
        private RepairType repairType;
    
        ...
    }
    

    请参阅Hibernate ORM documentation for more details

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-05-15
      • 2011-01-10
      • 2015-11-12
      • 1970-01-01
      相关资源
      最近更新 更多