【问题标题】:JPA: Map invalid database values to enumsJPA:将无效的数据库值映射到枚举
【发布时间】:2012-01-17 17:37:31
【问题描述】:

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

@Enumerated(EnumType.STRING)
private MySpecialEnum enumValue;

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

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

顺便说一句:我正在使用 WebSphere Application Server 中附带的 OpenJpa。

【问题讨论】:

    标签: java jpa openjpa


    【解决方案1】:

    您可以将枚举类型字段映射为@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();
    }
    

    【讨论】:

    • 非常感谢您的回答。但我正在寻找更通用的解决方案。对于您建议的方式,我必须为每个枚举字段编写此代码,但我必须为我的数据模型中的所有枚举字段实现它。顺便说一句,我喜欢让我的实体简单而愚蠢。
    【解决方案2】:

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

    【讨论】:

      猜你喜欢
      • 2011-05-27
      • 1970-01-01
      • 2020-12-13
      • 2016-12-13
      • 1970-01-01
      • 1970-01-01
      • 2018-04-11
      • 2010-09-29
      • 1970-01-01
      相关资源
      最近更新 更多