Hibernateでの列挙


82

DAOに、値がJava列挙から取得されるフィールドがあると便利なことがよくあります。典型的な例はログインDAOで、通常、ユーザーを「NORMAL」または「ADMIN」として特徴付けるフィールドがあります。Hibernateでは、次の2つのオブジェクトを使用して、この関係を(半)タイプセーフな方法で表現します。

class User {
    String username;
    String passwd;
    UserType type;
}

class UserType {
    private enum Type {ADMIN, NORMAL};
    private String type;

    //Setters/Getters for Hibernate
    public void setType(String type);
    public String getType();

    //Setters/Getters for user
    public void setUserType(UserType.Type t);
    public UserType.Type getUserType();

    public static UserType fromType(UserType.Type t);
}

これは機能しますが、UserTypeクラスが不格好で、いくつかの値を格納するためだけに官僚主義が多すぎることがわかりました。理想的には、Hibernateは列挙型フィールドを直接サポートし、列挙値を格納するための追加のテーブルを作成する必要があります。

私の質問は:Hibernateで列挙型クラスを直接マップする方法はありますか?そうでない場合、列挙を表すための私のパターンは十分に良いですか、それとも何かが欠けていますか?人々は他にどのようなパターンを使用していますか?

回答:


110

HibernateまたはJPAアノテーションの使用:

class User {
   @Enumerated(EnumType.STRING)
   UserType type
}

UserTypeは、単なる標準のJava5列挙型です。

これが注釈だけに限定されているとは想像できませんが、hbmファイルでこれを行う方法は実際にはわかりません。バージョンに大きく依存する可能性があると思いますが、休止状態の3.2以降が必要であると確信しています。

編集:それはhbmで可能ですが、少し厄介です、このフォーラムスレッドを見てください


3
@Enumerated(EnumType.ORDINAL)は、どのintにマップするのがより効率的でしょうか?
Lee Chee Kiam 2011年

4
おそらくもっと効率的ですが、実際のシステムで違いを測定できないことにお金をかけます。@Enumeratedを実行した場合、実際にはEnumType.ORDINALがデフォルトになります。ほとんどの人(特にDBA)は、DB内の列挙型の名前を好む傾向があると思います。
ガレスデイビス

1
これらの列挙型の列の長さを変更するにはどうすればよいですか?列アノテーションを追加しようとしましたが、それは尊重されませんか?
Kannan Ekanath 2011

2
別の質問としてそれを尋ねる必要があります。
Gareth Davis

2
順序に関係なく列挙型に要素を追加できるため、ORDINALではなくSTRINGを使用してください。
Matthew Daumen 2014年

14

Hibernateのドキュメントから:http//www.hibernate.org/272.html

列挙型ごとに新しいtypedefを作成し、propertyタグでtypedefを参照できます。

マッピングの例-インライン<type>タグ

  <property name='suit'>
    <type name="EnumUserType">
      <param name="enumClassName">com.company.project.Suit</param>
    </type>
  </property>

マッピングの例-を使用 <typedef>

  <typedef name="suit" class='EnumUserType'>
      <param name="enumClassName">com.company.project.Suit</param>
  </typedef>

  <class ...>
    <property name='suit' type='suit'/>
  </class>

ありがとう。私はすでにその解決策を知っていました。問題は、すべての列挙型でHibernate内部型を使用する必要があることです。これにより、私の場合のようにDAOをDTOとして使用している場合に問題が発生する可能性があります。より良い解決策は実際にここで説明されています: hibernate.org/273.html
Georgios Gousios 2009年

1
新しいバージョンでは、パラメータ名がのenumClass代わりになっていることに注意してくださいenumClassName
ライアンランズフォード2011
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.