사용자 도구

사이트 도구


java:jpa:enum

차이

문서의 선택한 두 판 사이의 차이를 보여줍니다.

차이 보기로 링크

양쪽 이전 판 이전 판
java:jpa:enum [2014/10/01 21:16]
kwon37xi
java:jpa:enum [2014/10/02 16:40]
kwon37xi
줄 1: 줄 1:
-====== JPA 2.0 Enum Mapping with Hibernate ====== +====== JPA Enum ====== 
-  * [[http://appfuse.org/display/APF/Java+5+Enums+Persistence+with+Hibernate|Java 5 Enums Persistence with Hibernate]]+  * 기본적으로 Enum의 ''name()''이 문자열로 DB에 저장. 
 +  * ORDINAL은 사용하지 말 것. Enum의 순서 변경시 심각한 마이그레이션 이슈를 일으킴.
   * JPA 2.0에서는 ENUM값을 자유롭게 변경해서 넣을 때 문제가 있다. JPA 2.1에서는 Converter가 있어서 관계 없음.   * JPA 2.0에서는 ENUM값을 자유롭게 변경해서 넣을 때 문제가 있다. JPA 2.1에서는 Converter가 있어서 관계 없음.
- +  JPA 2.0는 [[java:hibernate:usertype:generic_enum|Hibernate Generic Enum UserType]] 사용.
-====== Hibernate UserType ====== +
-  [[https://developer.jboss.org/wiki/Java5EnumUserType|Java 5 EnumUserType]] +
-  * [[http://stackoverflow.com/questions/4744179/java-lang-verifyerror-on-hibernate-specific-usertype/6231710#6231710|java.lang.verifyError on hibernate specific usertype for Hibernate 4 - Stack Overflow]] +
-  * 위 두 링크에 는 UserType을 Hibernate 4 용으로 변환한 것. [[java:hibernate:usertype|Hibernate User Type]] 참조. +
- +
-<code java> +
-public class GenericEnumUserType implements UserType, ParameterizedType { +
- +
- /** 대상 enum 클래스를 문자열로 지정한다 */ +
- public static final String PARAM_ENUM_CLASS = "enumClass"; +
- +
- /** Enum을 실제 저장할 문자열로 바꿔주는 메소드. 이 메소드의 리턴타입은 PARAM_VALUE_OF_METHOD로 지정된 메소드의 파라미터와 같은 타입이어야 한다. */ +
- public static final String PARAM_IDENTIFIER_METHOD = "identifierMethod"; +
- private static final String DEFAULT_IDENTIFIER_METHOD_NAME = "name"; +
- +
- /** 저장된 데이터로부터 Enum을 리턴해주는 메소드. 이 메소드의 파라미터 타입은 PARAM_IDENTIFIER_METHOD로 지정된 메소드의 리턴 타입과 같아야 한다. */ +
- public static final String PARAM_VALUE_OF_METHOD = "valueOfMethod"; +
- private static final String DEFAULT_VALUE_OF_METHOD_NAME = "valueOf"; +
- +
- private Class<? extends Enum> enumClass; +
- private Class<?> identifierType; +
- private Method identifierMethod; +
- private Method valueOfMethod; +
- private AbstractSingleColumnStandardBasicType type; +
- private int[sqlTypes; +
- +
- @Override +
- public void setParameterValues(Properties parameters) { +
- String enumClassName = parameters.getProperty(PARAM_ENUM_CLASS); +
- +
- try { +
- enumClass = Class.forName(enumClassName).asSubclass(Enum.class); +
- } catch (ClassNotFoundException exception) { +
- throw new HibernateException("Enum class not found", exception); +
-+
- +
- String identifierMethodName = parameters.getProperty(PARAM_IDENTIFIER_METHOD, DEFAULT_IDENTIFIER_METHOD_NAME); +
- +
- try { +
- identifierMethod = enumClass.getMethod(identifierMethodName, new Class[0]); +
- identifierType = identifierMethod.getReturnType(); +
- } catch (Exception exception) { +
- throw new HibernateException("Failed to optain identifier method", exception); +
-+
- +
- TypeResolver tr = new TypeResolver(); +
- type = (AbstractSingleColumnStandardBasicType) tr.basic(identifierType.getName()); +
- +
- if (type == null) { +
- throw new HibernateException("Unsupported identifier type " + identifierType.getName()); +
-+
- sqlTypes = new int[] { type.sqlType() }; +
- +
- String valueOfMethodName = parameters.getProperty(PARAM_VALUE_OF_METHOD, DEFAULT_VALUE_OF_METHOD_NAME); +
- +
- try { +
- valueOfMethod = enumClass.getMethod(valueOfMethodName, new Class[] { identifierType }); +
- } catch (Exception exception) { +
- throw new HibernateException("Failed to optain valueOf method", +
- exception); +
-+
-+
- +
- @Override +
- public Class returnedClass() { +
- return enumClass; +
-+
- +
- @Override +
- public Object nullSafeGet(ResultSet rs, String[] names, SessionImplementor session, Object owner) throws HibernateException, SQLException { +
- Object identifier = type.get(rs, names[0], session); +
- try { +
- return valueOfMethod.invoke(enumClass, new Object[] { identifier }); +
- } catch (Exception exception) { +
- throw new HibernateException("Exception while invoking valueOfMethod of enumeration class: ", +
- exception); +
-+
-+
- +
- @Override +
- public void nullSafeSet(PreparedStatement st, Object value, int index, SessionImplementor session) throws HibernateException, SQLException { +
- try { +
- Object identifier = value != null ? identifierMethod.invoke(value, new Object[0]) : null; +
- st.setObject(index, identifier); +
- } catch (Exception exception) { +
- throw new HibernateException("Exception while invoking identifierMethod of enumeration class: ", +
- exception); +
-+
-+
- +
- @Override +
- public int[] sqlTypes() { +
- return sqlTypes; +
-+
- +
- @Override +
- public Object assemble(Serializable cached, Object owner) throws HibernateException { +
- return cached; +
-+
- +
- @Override +
- public Object deepCopy(Object value) throws HibernateException { +
- return value; +
-+
- +
- @Override +
- public Serializable disassemble(Object value) throws HibernateException { +
- return (Serializable) value; +
-+
- +
- @Override +
- public boolean equals(Object x, Object y) throws HibernateException { +
- return x == y; +
-+
- +
- @Override +
- public int hashCode(Object x) throws HibernateException { +
- return x.hashCode(); +
-+
- +
- public boolean isMutable() { +
- return false; +
-+
- +
- public Object replace(Object original, Object target, Object owner) throws HibernateException { +
- return original; +
-+
-+
-</code> +
- +
-===== Example ===== +
-<code java> +
-package org.appfuse.tutorial.model; +
-  +
-@Entity +
-@Table(name="t_person"+
-public class Person extends BaseObject { +
-  +
-   // Enumerations --------------------------- +
-     public enum Sex{ +
-  +
-      MALE(1), +
-      FEMALE(2); +
-  +
-      private int value; +
-  +
-      Sex(int value) { +
-          this.value = value; +
-      } +
-  +
-      // the identifierMethod +
-      public int toInt() { +
-        return value; +
-      } +
-  +
-       // the valueOfMethod +
-       public  static Sex fromInt(int value) {    +
-           switch(value) { +
-               case 1: return MALE; +
-               case 2: return FEMALE; +
-               default: +
-                       return UNKNOW; +
-           } +
-      } +
-       +
-      public String toString() { +
-        switch(this) { +
-          case MALE: +
-              return "Male"; +
-          case FEMALE: +
-              return "Female"; +
-        } +
-      } +
-    } +
-  +
-    // Attributes --------------------------- +
-  +
-    @Id +
-    @Column(name= "person_id"+
-    @GeneratedValue(strategy = GenerationType.AUTO) +
-    private Long id; +
-  +
-  +
-    @Column(name="person_firstname", length = 50, nullable = false) +
-    private String firstName; +
-  +
-  +
-    @Column(name="person_lastname", length = 50, nullable = false) +
-    private String lastName; +
-  +
-     +
-    @Column(name= "person_sex", columnDefinition="integer", nullable = true) +
-    @Type( +
-        type = "org.appfuse.tutorial.commons.hibernate.GenericEnumUserType", +
-        parameters = { +
-                @Parameter( +
-                    name  = "enumClass",                      +
-                    value = "org.appfuse.tutorial.model.Person$Sex"), +
-                @Parameter( +
-                    name  = "identifierMethod", +
-                    value = "toInt"), +
-                @Parameter( +
-                    name  = "valueOfMethod", +
-                    value = "fromInt"+
-                } +
-    ) +
-    private Sex sex; +
-  +
-  +
-    /* +
-     * Getters and Setters ... +
-     */ +
-+
-</code>+
java/jpa/enum.txt · 마지막으로 수정됨: 2014/10/02 16:40 저자 kwon37xi