JPA:将无效的数据库值映射到枚举

时间:2012-01-17 17:37:31

标签: java jpa openjpa

在我的数据模型中,a有许多实体,其中属性映射到这样的枚举:

@Enumerated(EnumType.STRING)
private MySpecialEnum enumValue;

MySpecialEnum定义了一些固定值。映射工作正常,如果数据库为列保留NULL值,我也会在enumValue属性中获取NULL。 问题是,我的后端模块(我没有影响)使用CHAR列中的空格来标识没有设置值。所以我得到一个IllegalArgumentException而不是NULL值。

所以我的问题是:是否有一个JPA事件,我可以在映射到enum-attribute之前更改从数据库读取的值? 对于写访问,有@PrePersist,我可以在其中将Null值更改为空格。我知道有@ PostLoad事件,但这是在映射后处理的。

顺便说一下:我正在使用WebSphere Application Server中提供的OpenJpa。

2 个答案:

答案 0 :(得分:0)

您可以将枚举类型字段映射为@Transient(它不会被保留)并将另一个字段直接映射为字符串,并在@PostLoad中同步它们:

@Transient
private MyEnum fieldProxy;

private String fieldDB;

@PostLoad
public void postLoad() {
    if (" ".equals(fieldDB))
         fieldProxy = null;
    else
         fieldProxy = MyEnum.valueOf(fieldDB);
}

在Java代码中使用get/setFieldProxy()

至于同步另一种方式,我会在setter中而不是@PreUpdate中进行,因为对@Transient字段的更改可能不会将实体标记为已修改且更新操作可能不被触发(我不确定):

public void setFieldProxy(MyEnum value) {
    fieldProxy = value;
    if (fieldProxy == null)
       fieldDB = " ";
    else
       fieldDB = value.name();
}

答案 1 :(得分:0)

OpenJPA提供@Externalizer@Factory来处理“特殊”数据库值。

请参阅:http://ci.apache.org/projects/openjpa/2.0.x/manual/manual.html#ref_guide_pc_extern_values

你可能会得到这样的结论:未经过测试......

@Factory("MyClass.mySpecialEnumFactory")
private MySpecialEnum special;

...

public static MySpecialEnum mySpecialEnumFactory(String external) {
   if(StringUtils.isBlank(external) return null; // or why not MySpecialEnum.NONE;
   return MySpecialEnum.valueOf(external);
}