2012-01-17 8 views
0

を列挙型にする地図無効なデータベースの値が属性は、このような列挙型にマッピングされている多くの企業があります。JPA:私のデータモデルAに

@Enumerated(EnumType.STRING) 
private MySpecialEnum enumValue; 

をMySpecialEnumは、いくつかの固定値を定義します。マッピングは正常に動作し、データベースがカラムのNULL値を保持している場合、enumValue属性にもNULLが返されます。 問題は、私の影響を受けていないバックエンドモジュールが、値が設定されていないことを識別するためにCHAR列のスペースを使用していることです。だから私はNULL値の代わりにIllegalArgumentExceptionを取得します。

私の質問は:enum属性にマッピングする前に、データベースから読み取った値を変更できるJPAイベントはありますか? 書き込みアクセスには、@PrePersistがあります。ここでは、空値をスペースに変更できます。私は@ PostLoadイベントがあることを知っていますが、これはマッピングの後で処理されます。

Btw:WebSphere Application Serverに同梱のOpenJpaを使用しています。

答えて

0

あなたは@Transientとして列挙型のフィールドをマップする(それが永続化されません)と@PostLoadでそれらを同期、直接文字列として別のフィールドをマップすることができます:

@Transient 
private MyEnum fieldProxy; 

private String fieldDB; 

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

使用get/setFieldProxy() Javaコードで。

@Transientのフィールドに変更が加えられているため、更新操作がトリガされない可能性があるので、私は​​ではなく、セッターでやります)こののわからない:

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

おかげで多くのことを

はこれを参照してください。しかし、私はより一般的な解決策を探しています。あなたは、私はすべての単一の列挙型フィールドのためにこのコードを記述する必要が示唆されているが、私はそれを私のデータモデルのすべての列挙型フィールドのために実装する必要があります。 Btw私はエンティティを単純かつ愚かに保つのが好きです。 –

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