Aufzählungen im Ruhezustand

82

Es ist oft nützlich, ein Feld in einem DAO zu haben, dessen Wert aus einer Java-Aufzählung stammt. Ein typisches Beispiel ist ein Anmelde-DAO, in dem Sie normalerweise ein Feld haben, das den Benutzer als "NORMAL" oder "ADMIN" kennzeichnet. Im Ruhezustand würde ich die folgenden 2 Objekte verwenden, um diese Beziehung (halb-) typsicher darzustellen:

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

Dies funktioniert, aber ich finde die UserType-Klasse ungly und erfordert zu viel Bürokratie, um nur ein paar Werte zu speichern. Im Idealfall sollte der Ruhezustand Aufzählungsfelder direkt unterstützen und eine zusätzliche Tabelle zum Speichern der Aufzählungswerte erstellen.

Meine Frage ist: Gibt es eine Möglichkeit, eine Aufzählungsklasse im Ruhezustand direkt zuzuordnen? Wenn nicht, ist mein Muster für die Darstellung von Aufzählungen gut genug oder fehlt mir etwas? Welche anderen Muster verwenden Menschen?

Georgios Gousios
quelle

Antworten:

110

Verwenden von Annotationen im Ruhezustand oder JPA:

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

UserType ist nur eine Standard-Java 5-Aufzählung.

Ich kann mir nicht vorstellen, dass dies nur auf Anmerkungen beschränkt ist, aber ich weiß nicht, wie ich das mit hbm-Dateien machen soll. Es kann sehr versionabhängig sein, aber ich bin mir ziemlich sicher, dass der Ruhezustand 3.2+ erforderlich ist.

edit: es ist in einem hbm möglich, ist aber etwas chaotisch, schau dir diesen forum thread an

Gareth Davis
quelle
3
Könnte @Enumerated (EnumType.ORDINAL) welche Zuordnung zu int effizienter machen?
Lee Chee Kiam
4
Wahrscheinlich ist es effizienter, aber ich würde Geld dafür investieren, dass ich den Unterschied in einem realen System nicht messen kann. EnumType.ORDINAL ist eigentlich die Standardeinstellung, wenn Sie nur @Enumerated ausführen. Ich denke, die meisten Leute (besonders DBAs) bevorzugen den Namen der Aufzählung in der DB.
Gareth Davis
1
Wie kann ich die Spaltenlänge für diese Aufzählungen ändern? Ich habe versucht, die Spaltenanmerkung hinzuzufügen, aber das wird nicht berücksichtigt?
Kannan Ekanath
2
Sie müssen das als eine andere Frage stellen.
Gareth Davis
2
Verwenden Sie den STRING anstelle von ORDINAL, da Sie der Aufzählung unabhängig von der Reihenfolge zusätzliche Elemente hinzufügen können.
Matthew Daumen
15

Aus der Hibernate-Dokumentation: http://www.hibernate.org/272.html

Sie können für jede Ihrer Aufzählungen ein neues typedef erstellen und auf die typedefs im Eigenschaftstag verweisen.

Beispielzuordnung - Inline- <type>Tag

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

Beispiel Mapping - using <typedef>

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

  <class ...>
    <property name='suit' type='suit'/>
  </class>
Craig
quelle
Vielen Dank. Diese Lösung war mir bereits bekannt. Das Problem ist, dass alle Ihre Aufzählungen hibernate-interne Typen verwenden müssen, was zu Problemen führen kann, wenn Sie die DAOs wie in meinem Fall als DTOs verwenden. Eine bessere Lösung ist eigentlich hier beschrieben: hibernate.org/273.html
Georgios Gousios
1
Beachten Sie, dass in neueren Versionen der Parametername enumClassanstelle von lautet enumClassName.
Ryan Ransford