2016-03-02 54 views
1

我想刪除遺留項目上的代碼重複。所以我設計了一個基本類如IoeBase如何覆蓋JPA中的枚舉字段映射

但是有些子類不遵循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; 

// ... 
} 
+0

你是什麼意義呢?你想實現什麼?你想從'IoeBase'對象訪問'theValue'字段嗎?或者你只是不想重複所有子類的映射? –

+0

謝謝。我正在重建一個遺留項目。在重新構造之後,在基類中,值字段映射爲EnumType.STRING。大多數子類使用這種映射,但是一個子類使用EnumType.ORDINAL映射。 – Raymond

回答

1

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]; 
    } 
}