문서의 선택한 두 판 사이의 차이를 보여줍니다.
양쪽 이전 판 이전 판 다음 판 | 이전 판 마지막 판 양쪽 다음 판 | ||
java:jpa:enum [2014/10/01 18:04] kwon37xi |
java:jpa:enum [2014/10/01 21:16] kwon37xi |
||
---|---|---|---|
줄 2: | 줄 2: | ||
* [[http:// | * [[http:// | ||
* JPA 2.0에서는 ENUM값을 자유롭게 변경해서 넣을 때 문제가 있다. JPA 2.1에서는 Converter가 있어서 관계 없음. | * JPA 2.0에서는 ENUM값을 자유롭게 변경해서 넣을 때 문제가 있다. JPA 2.1에서는 Converter가 있어서 관계 없음. | ||
- | * [[https:// | ||
====== Hibernate UserType ====== | ====== Hibernate UserType ====== | ||
+ | * [[https:// | ||
+ | * [[http:// | ||
+ | * 위 두 링크에 있는 UserType을 Hibernate 4 용으로 변환한 것. [[java: | ||
+ | |||
<code java> | <code java> | ||
- | package org.appfuse.tutorial.commons.hibernate; | ||
- | |||
- | import java.io.Serializable; | ||
- | import java.lang.reflect.Method; | ||
- | import java.sql.PreparedStatement; | ||
- | import java.sql.ResultSet; | ||
- | import java.sql.SQLException; | ||
- | import java.util.Properties; | ||
- | |||
- | import org.hibernate.HibernateException; | ||
- | import org.hibernate.type.NullableType; | ||
- | import org.hibernate.type.TypeFactory; | ||
- | import org.hibernate.usertype.ParameterizedType; | ||
- | import org.hibernate.usertype.UserType; | ||
- | |||
- | |||
public class GenericEnumUserType implements UserType, ParameterizedType { | public class GenericEnumUserType implements UserType, ParameterizedType { | ||
- | | + | |
- | private static final String DEFAULT_VALUE_OF_METHOD_NAME = " | + | /** 대상 enum 클래스를 문자열로 지정한다 */ |
- | + | public static final String PARAM_ENUM_CLASS = " | |
- | private Class<? extends Enum> enumClass; | + | |
- | private Class<?> | + | /** Enum을 실제 저장할 문자열로 바꿔주는 메소드. 이 메소드의 리턴타입은 PARAM_VALUE_OF_METHOD로 지정된 메소드의 파라미터와 같은 타입이어야 한다. */ |
- | private Method identifierMethod; | + | public static final String PARAM_IDENTIFIER_METHOD = " |
- | private Method valueOfMethod; | + | private static final String DEFAULT_IDENTIFIER_METHOD_NAME = " |
- | private | + | |
- | private int[] sqlTypes; | + | /** 저장된 데이터로부터 Enum을 리턴해주는 메소드. 이 메소드의 파라미터 타입은 PARAM_IDENTIFIER_METHOD로 지정된 메소드의 리턴 타입과 같아야 한다. */ |
- | + | public static final String PARAM_VALUE_OF_METHOD = " | |
- | public void setParameterValues(Properties parameters) { | + | private static final String DEFAULT_VALUE_OF_METHOD_NAME = " |
- | String enumClassName = parameters.getProperty(" | + | |
- | try { | + | private Class<? extends Enum> enumClass; |
- | enumClass = Class.forName(enumClassName).asSubclass(Enum.class); | + | private Class<?> |
- | } catch (ClassNotFoundException | + | private Method identifierMethod; |
- | throw new HibernateException(" | + | private Method valueOfMethod; |
- | } | + | private |
- | + | private int[] sqlTypes; | |
- | String identifierMethodName = parameters.getProperty(" | + | |
- | + | @Override | |
- | try { | + | public void setParameterValues(Properties parameters) { |
- | identifierMethod = enumClass.getMethod(identifierMethodName, | + | String enumClassName = parameters.getProperty(PARAM_ENUM_CLASS); |
- | identifierType = identifierMethod.getReturnType(); | + | |
- | } catch (Exception | + | try { |
- | throw new HibernateException(" | + | enumClass = Class.forName(enumClassName).asSubclass(Enum.class); |
- | } | + | } catch (ClassNotFoundException |
- | + | throw new HibernateException(" | |
- | type = (NullableType) TypeFactory.basic(identifierType.getName()); | + | } |
- | + | ||
- | if (type == null) | + | String identifierMethodName = parameters.getProperty(PARAM_IDENTIFIER_METHOD, DEFAULT_IDENTIFIER_METHOD_NAME); |
- | throw new HibernateException(" | + | |
- | + | try { | |
- | sqlTypes = new int[] { type.sqlType() }; | + | identifierMethod = enumClass.getMethod(identifierMethodName, |
- | + | identifierType = identifierMethod.getReturnType(); | |
- | String valueOfMethodName = parameters.getProperty(" | + | } catch (Exception |
- | + | throw new HibernateException(" | |
- | try { | + | } |
- | valueOfMethod = enumClass.getMethod(valueOfMethodName, | + | |
- | } catch (Exception | + | TypeResolver tr = new TypeResolver(); |
- | throw new HibernateException(" | + | type = (AbstractSingleColumnStandardBasicType) tr.basic(identifierType.getName()); |
- | } | + | |
- | } | + | if (type == null) { |
- | + | throw new HibernateException(" | |
- | public Class returnedClass() { | + | } |
- | return enumClass; | + | sqlTypes = new int[] { type.sqlType() }; |
- | } | + | |
- | + | String valueOfMethodName = parameters.getProperty(PARAM_VALUE_OF_METHOD, DEFAULT_VALUE_OF_METHOD_NAME); | |
- | public Object nullSafeGet(ResultSet rs, String[] names, Object owner) throws HibernateException, | + | |
- | Object identifier = type.get(rs, | + | try { |
- | if (identifier == null) { | + | valueOfMethod = enumClass.getMethod(valueOfMethodName, |
- | return null; | + | } catch (Exception |
- | } | + | throw new HibernateException(" |
- | + | exception); | |
- | | + | } |
- | return valueOfMethod.invoke(enumClass, | + | } |
- | } catch (Exception | + | |
- | throw new HibernateException(" | + | @Override |
- | "enumeration class '" | + | public Class returnedClass() { |
- | } | + | return enumClass; |
- | } | + | } |
- | + | ||
- | public void nullSafeSet(PreparedStatement st, Object value, int index) throws HibernateException, | + | @Override |
- | try { | + | public Object nullSafeGet(ResultSet rs, String[] names, SessionImplementor session, Object owner) throws HibernateException, |
- | if (value == null) { | + | Object identifier = type.get(rs, |
- | st.setNull(index, | + | try { |
- | } else { | + | return valueOfMethod.invoke(enumClass, |
- | Object identifier = identifierMethod.invoke(value, | + | } catch (Exception |
- | type.set(st, identifier, index); | + | throw new HibernateException(" |
- | } | + | exception); |
- | | + | } |
- | throw new HibernateException(" | + | } |
- | "enumeration class '" | + | |
- | } | + | @Override |
- | } | + | public void nullSafeSet(PreparedStatement st, Object value, int index, SessionImplementor session) throws HibernateException, |
- | + | try { | |
- | public int[] sqlTypes() { | + | Object identifier = value != null ? identifierMethod.invoke(value, |
- | return sqlTypes; | + | st.setObject(index, identifier); |
- | } | + | } catch (Exception |
- | + | throw new HibernateException(" | |
- | public Object assemble(Serializable cached, Object owner) throws HibernateException { | + | exception); |
- | return cached; | + | } |
- | } | + | } |
- | + | ||
- | public Object deepCopy(Object value) throws HibernateException { | + | @Override |
- | return value; | + | public int[] sqlTypes() { |
- | } | + | return sqlTypes; |
- | + | } | |
- | public Serializable disassemble(Object value) throws HibernateException { | + | |
- | return (Serializable) value; | + | @Override |
- | } | + | public Object assemble(Serializable cached, Object owner) throws HibernateException { |
- | + | return cached; | |
- | public boolean equals(Object x, Object y) throws HibernateException { | + | } |
- | return x == y; | + | |
- | } | + | @Override |
- | + | public Object deepCopy(Object value) throws HibernateException { | |
- | public int hashCode(Object x) throws HibernateException { | + | return value; |
- | return x.hashCode(); | + | } |
- | } | + | |
- | + | @Override | |
- | public boolean isMutable() { | + | public Serializable disassemble(Object value) throws HibernateException { |
- | return false; | + | return (Serializable) value; |
- | } | + | } |
- | + | ||
- | public Object replace(Object original, Object target, Object owner) throws HibernateException { | + | @Override |
- | return original; | + | 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; | ||
+ | } | ||
} | } | ||
</ | </ |