如何在JPA中重写枚举字段映射

时间:2016-03-02 18:33:06

标签: java jpa

我想删除遗留项目中的代码重复。所以我设计了一个像IoeBase这样的基类。

但有些子类不遵循EnumType.STRING,他们期望EnumType.ORDINAL

如何实现映射覆盖?

@MappedSuperclass
public class IoeBase<E extends Enum> implements Serializable {
    private static final long serialVersionUID = -2643992981146184972L;

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private long id;

    // !!! THE PROBLEM !!!
    @Enumerated(EnumType.STRING)
    private E theValue;

   //...
}

@Entity
//
// @AttributeOverrides({
//        @AttributeOverride(name = "theValue", column = @Column(name = "theMm", columnDefinition = "BIGINT(20)"))
// })
public class IoeInheri extends IoeBase<IoeEnum> {
    private static final long serialVersionUID = -3629698185247120860L;

//// !!! I expected on this subclass !!!
//
//    @Enumerated(EnumType.ORDINAL)
//    private E theValue;

// ...
}

1 个答案:

答案 0 :(得分:2)

AttributeConverter解决了我的问题。

结合以下知识

我可以

  • 将重复的代码移至基类
  • 将子类映射到其旧表
  • 不更改数据库

在这个遗产项目中。

@MappedSuperclass
public class IoeBase<E extends Enum> implements Serializable {
    private static final long serialVersionUID = -2643992981146184972L;

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private long id;

//    @Enumerated(EnumType.STRING)  // do NOT specify mapping
    private E theValue;
// ...
}

//
// EnumType.ORDINAL -like mapping
//
@Entity
@Converts({
        @Convert(attributeName = "theValue", converter = IoeEnumOrdinalConverter.class)
})
@AttributeOverrides({
        @AttributeOverride(name = "theValue", column = @Column(name = "theMm", columnDefinition = "BIGINT(20)", nullable = false))
})
public class IoeInheri extends IoeBase<IoeEnum> {
    private static final long serialVersionUID = -3629698185247120860L;
}

//
// EnumType.STRING -like mapping
//
@Entity
@Converts({
        @Convert(attributeName = "theValue", converter = IoeEnumNameConverter.class)
})
@AttributeOverrides({
        @AttributeOverride(name = "theValue", column = @Column(columnDefinition = "VARCHAR(50)", nullable = false))
})
public class IoeInheriString extends IoeBase<IoeEnum> {
    private static final long serialVersionUID = -4395231501780833765L;
}


////////////////////////////////////////////////////////////
// converter classes

@Converter
public class IoeEnumNameConverter implements AttributeConverter<IoeEnum, String> {
    @Override
    public String convertToDatabaseColumn(IoeEnum attribute) {
        return attribute.name();
    }

    @Override
    public IoeEnum convertToEntityAttribute(String dbData) {
        return IoeEnum.valueOf(dbData);
    }
}

@Converter
public class IoeEnumOrdinalConverter implements AttributeConverter<IoeEnum, Integer> {
    @Override
    public Integer convertToDatabaseColumn(IoeEnum attribute) {
        return attribute.ordinal();
    }

    @Override
    public IoeEnum convertToEntityAttribute(Integer dbData) {
        int index = dbData;
        return IoeEnum.values()[index];
    }
}