문서의 선택한 두 판 사이의 차이를 보여줍니다.
다음 판 | 이전 판 다음 판 양쪽 다음 판 | ||
java:jpa:enum [2014/10/01 17:58] kwon37xi 만듦 |
java:jpa:enum [2014/10/01 21:01] kwon37xi |
||
---|---|---|---|
줄 1: | 줄 1: | ||
- | ====== JPA 2.0 Enum Mapping ====== | + | ====== JPA 2.0 Enum Mapping |
* [[http:// | * [[http:// | ||
* JPA 2.0에서는 ENUM값을 자유롭게 변경해서 넣을 때 문제가 있다. JPA 2.1에서는 Converter가 있어서 관계 없음. | * JPA 2.0에서는 ENUM값을 자유롭게 변경해서 넣을 때 문제가 있다. JPA 2.1에서는 Converter가 있어서 관계 없음. | ||
+ | ====== Hibernate UserType ====== | ||
+ | * [[https:// | ||
+ | * [[http:// | ||
+ | * 위 두 링크에 있는 UserType을 Hibernate 4 용으로 변환한 것. | ||
+ | <code java> | ||
+ | public class GenericEnumUserType implements UserType, ParameterizedType { | ||
+ | |||
+ | /** 대상 enum 클래스를 문자열로 지정한다 */ | ||
+ | public static final String PARAM_ENUM_CLASS = " | ||
+ | |||
+ | /** Enum을 실제 저장할 문자열로 바꿔주는 메소드. 이 메소드의 리턴타입은 PARAM_VALUE_OF_METHOD로 지정된 메소드의 파라미터와 같은 타입이어야 한다. */ | ||
+ | public static final String PARAM_IDENTIFIER_METHOD = " | ||
+ | private static final String DEFAULT_IDENTIFIER_METHOD_NAME = " | ||
+ | |||
+ | /** 저장된 데이터로부터 Enum을 리턴해주는 메소드. 이 메소드의 파라미터 타입은 PARAM_IDENTIFIER_METHOD로 지정된 메소드의 리턴 타입과 같아야 한다. */ | ||
+ | public static final String PARAM_VALUE_OF_METHOD = " | ||
+ | private static final String DEFAULT_VALUE_OF_METHOD_NAME = " | ||
+ | |||
+ | private Class<? extends Enum> enumClass; | ||
+ | private Class<?> | ||
+ | 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(" | ||
+ | } | ||
+ | |||
+ | String identifierMethodName = parameters.getProperty(PARAM_IDENTIFIER_METHOD, | ||
+ | |||
+ | try { | ||
+ | identifierMethod = enumClass.getMethod(identifierMethodName, | ||
+ | identifierType = identifierMethod.getReturnType(); | ||
+ | } catch (Exception exception) { | ||
+ | throw new HibernateException(" | ||
+ | } | ||
+ | |||
+ | TypeResolver tr = new TypeResolver(); | ||
+ | type = (AbstractSingleColumnStandardBasicType) tr.basic(identifierType.getName()); | ||
+ | |||
+ | if (type == null) { | ||
+ | throw new HibernateException(" | ||
+ | } | ||
+ | sqlTypes = new int[] { type.sqlType() }; | ||
+ | |||
+ | String valueOfMethodName = parameters.getProperty(PARAM_VALUE_OF_METHOD, | ||
+ | |||
+ | try { | ||
+ | valueOfMethod = enumClass.getMethod(valueOfMethodName, | ||
+ | } catch (Exception exception) { | ||
+ | throw new HibernateException(" | ||
+ | exception); | ||
+ | } | ||
+ | } | ||
+ | |||
+ | @Override | ||
+ | public Class returnedClass() { | ||
+ | return enumClass; | ||
+ | } | ||
+ | |||
+ | @Override | ||
+ | public Object nullSafeGet(ResultSet rs, String[] names, SessionImplementor session, Object owner) throws HibernateException, | ||
+ | Object identifier = type.get(rs, | ||
+ | try { | ||
+ | return valueOfMethod.invoke(enumClass, | ||
+ | } catch (Exception exception) { | ||
+ | throw new HibernateException(" | ||
+ | exception); | ||
+ | } | ||
+ | } | ||
+ | |||
+ | @Override | ||
+ | public void nullSafeSet(PreparedStatement st, Object value, int index, SessionImplementor session) throws HibernateException, | ||
+ | try { | ||
+ | Object identifier = value != null ? identifierMethod.invoke(value, | ||
+ | st.setObject(index, | ||
+ | } catch (Exception exception) { | ||
+ | throw new HibernateException(" | ||
+ | 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; | ||
+ | } | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | ===== Example ===== | ||
+ | <code java> | ||
+ | package org.appfuse.tutorial.model; | ||
+ | |||
+ | @Entity | ||
+ | @Table(name=" | ||
+ | public class Person extends BaseObject { | ||
+ | |||
+ | // Enumerations --------------------------- | ||
+ | | ||
+ | |||
+ | MALE(1), | ||
+ | FEMALE(2); | ||
+ | |||
+ | private int value; | ||
+ | |||
+ | Sex(int value) { | ||
+ | this.value = value; | ||
+ | } | ||
+ | |||
+ | // the identifierMethod | ||
+ | public int toInt() { | ||
+ | return value; | ||
+ | } | ||
+ | |||
+ | // the valueOfMethod | ||
+ | | ||
+ | | ||
+ | case 1: return MALE; | ||
+ | case 2: return FEMALE; | ||
+ | | ||
+ | | ||
+ | } | ||
+ | } | ||
+ | | ||
+ | public String toString() { | ||
+ | switch(this) { | ||
+ | case MALE: | ||
+ | return " | ||
+ | case FEMALE: | ||
+ | return " | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | |||
+ | // Attributes --------------------------- | ||
+ | |||
+ | @Id | ||
+ | @Column(name= " | ||
+ | @GeneratedValue(strategy = GenerationType.AUTO) | ||
+ | private Long id; | ||
+ | |||
+ | |||
+ | @Column(name=" | ||
+ | private String firstName; | ||
+ | |||
+ | |||
+ | @Column(name=" | ||
+ | private String lastName; | ||
+ | |||
+ | | ||
+ | @Column(name= " | ||
+ | @Type( | ||
+ | type = " | ||
+ | parameters = { | ||
+ | @Parameter( | ||
+ | name = " | ||
+ | value = " | ||
+ | @Parameter( | ||
+ | name = " | ||
+ | value = " | ||
+ | @Parameter( | ||
+ | name = " | ||
+ | value = " | ||
+ | } | ||
+ | ) | ||
+ | private Sex sex; | ||
+ | |||
+ | |||
+ | /* | ||
+ | * Getters and Setters ... | ||
+ | */ | ||
+ | } | ||
+ | </ |