web-dev-qa-db-ja.com

Hibernate列挙型マッピング

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

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から取得する方法がわかりません(インスタンス化を試みるカスタムマッパーが必要ですか?指定された列挙型クラスを使用する列挙型?Hibernateはこの機能をネイティブにサポートしていますか?).

16
dm3

カスタム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>

編集:Hibernateには独自のEnumTypeが付属しています(hibernate-annotationsの3.2以降、hibernate-coreの3.6以降-執筆時点ではhibernate-annotationsにあることを知りませんでしたが、 Diegoの回答 を参照してください。 =)。

7
sfussenegger

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)を使用してください。ここで確認してください:

Hibernateの列挙

50
Diego Pino