2009-10-20 18 views
16

事前にインターフェイスを実装していなかったenumを、@Enumerated(EnumType.STRING)を使って所有者クラスと同じテーブルにenumを格納する既存のデータベースにマップする必要があります。Hibernate enum mapping

class A { 
    HasName name; 
} 

interface HasName { 
    String getName(); 
} 

enum X implements HasName { 
    John, Mary; 

    public String getName() { return this.name(); } 
} 

enum Y implements HasName { 
    Tom, Ann; 

    public String getName() { return this.name(); } 
} 

この場合、マッピングをどのように処理する必要がありますか?インターフェイスを実装するすべての列挙型が異なる値を持つため、データベースへの永続化は変更されませんが、DBからオブジェクトを取得する方法がわかりません(カスタムマッパーが必要ですか? enumは指定された列挙型クラスを使用していますか?Hibernateはネイティブにこの機能をサポートしていますか?

答えて

7

それはカスタムUserType(例えばthis one)を作成し、マッピングから

<property name="type" not-null="true"> 
    <type name="at.molindo.util.hibernate.EnumUserType"> 
    <param name="enumClass"> 
     com.example.MyEnum 
    </param> 
    </type> 
</property> 

EDITそれを使用することが可能です:Hibernateは休止状態コアで3.6以降、休止状態、注釈で3.2以降(それ自身のEnumTypeが付属していますが - 執筆時には、それが休止状態の注釈であることは知らなかったが、Diego's answerを参照)。

+0

私の場合は、列挙型のクラスがどうなるか分かりません。 'A'をインスタンス化するとき、Hibernateは{X、Y}列挙の1つを選ぶ必要があります。 – dm3

+0

サンプルのUserType実装を必要に応じて調整するのは難しいことではありません。たとえば、値だけを保存する代わりに、クラスを保存することもできます(例:com.example.X.JohnまたはX.Johnですが、Xからcom.example.Xへのマッピングが必要です) – sfussenegger

+0

Iを意味しますカスタムマッパーが必要です(pastebinへのリンクが表示されませんでした)。答えをありがとう。 – dm3

50

Hibernateは列挙型をマップするためにorg.hibernate.type.EnumTypeを提供します。例えば、次に

package com.igalia.enumerates; 

public enum Status { 
    BUSY, 
    AVAILABLE; 
} 

package com.igalia.entities; 

class MyClass { 
    private Status status; 
} 

、次のようにあなたのHibernateマッピングを行います。

<class name="MyClass"> 
    <id name="id"> 
     <generator class="native"/> 
    </id> 

    <property name="status"> 
     <type name="org.hibernate.type.EnumType"> 
     <param name="enumClass">com.igalia.enumerates.Status</param> 
     </type> 
    </property> 
</class> 

そして、それはそれです。 hbm.xmlの代わりにJPAアノテーションを使用する場合は、@ Enumerated(EnumType.STRING)を使用します。ここでそれを確認してください:

Enumerations in Hibernate

+0

どのようにデフォルト値を設定しますか?私は次の要素をに追加しましたが、それは私のためには機能しませんでした: Timo

+1

@valmarクラスレベルで* status *を初期化することができます(またはそのコンストラクタで行うこともできます)。たとえば、 'private status status = Status.BUSY;' –

関連する問題