如何在JPA中覆盖Enum字段映射 [英] How to override Enum field mapping in JPA

查看:83
本文介绍了如何在JPA中覆盖Enum字段映射的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想删除旧项目上的代码重复.因此,我设计了一个IoeBase之类的基类.

I wanna remove code duplication on a legacy project. So I designed a base class like IoeBase.

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

But some subclass do not following the EnumType.STRING, they expected 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;

// ...
}

推荐答案

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

这篇关于如何在JPA中覆盖Enum字段映射的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆