Created
July 17, 2012 13:48
-
-
Save u1hoshino/3129488 to your computer and use it in GitHub Desktop.
Hibernate Enum UserType
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package sample; | |
import java.io.Serializable; | |
import java.sql.PreparedStatement; | |
import java.sql.ResultSet; | |
import java.sql.SQLException; | |
import java.sql.Types; | |
import java.util.Properties; | |
import org.hibernate.HibernateException; | |
import org.hibernate.engine.spi.SessionImplementor; | |
import org.hibernate.type.AbstractStandardBasicType; | |
import org.hibernate.type.IntegerType; | |
import org.hibernate.type.StringType; | |
import org.hibernate.usertype.EnhancedUserType; | |
import org.hibernate.usertype.ParameterizedType; | |
public abstract class AbstractEnumUserType<E extends Enum<E>, V> implements | |
EnhancedUserType, ParameterizedType { | |
public static int DEAFAULT_SQL_TYPE = Types.INTEGER; | |
private PreparedStatementSetter psSetter; | |
private AbstractStandardBasicType<?> basicType; | |
protected abstract Class<E> getEnumClass(); | |
protected abstract Class<V> getValueClass(); | |
protected abstract E convertEnum(V rawValue); | |
protected abstract V convertSqlValue(E enumValue); | |
protected int getSqlType() { | |
// 起動時にしか呼ばれないはず? | |
int sqlType = Types.OTHER; | |
switch (getValueClass().getName()) { | |
case "java.lang.String": | |
sqlType = Types.VARCHAR; | |
break; | |
case "java.lang.Integer": | |
sqlType = Types.INTEGER; | |
break; | |
default: | |
break; | |
} | |
return sqlType; | |
} | |
// //////////////////////////// | |
@Override | |
public int[] sqlTypes() { | |
return new int[] { getSqlType() }; | |
} | |
@Override | |
public Class<?> returnedClass() { | |
return getEnumClass(); | |
} | |
@Override | |
public boolean equals(Object x, Object y) throws HibernateException { | |
return (x == y); | |
} | |
@Override | |
public int hashCode(Object x) throws HibernateException { | |
return (x == null) ? 0 : x.hashCode(); | |
} | |
@Override | |
public Object nullSafeGet(ResultSet rs, String[] names, | |
SessionImplementor session, Object owner) | |
throws HibernateException, SQLException { | |
Object rawValue = basicType.nullSafeGet(rs, names[0], session, owner); | |
Object enumValue = (rawValue == null) ? null | |
: convertEnum((V) rawValue); | |
return enumValue; | |
} | |
@Override | |
public void nullSafeSet(PreparedStatement st, Object value, int index, | |
SessionImplementor session) throws HibernateException, SQLException { | |
if (value == null) { | |
st.setNull(index, Types.VARCHAR); | |
} else { | |
psSetter.set(st, convertSqlValue((E) value), index); | |
} | |
} | |
@Override | |
public Object deepCopy(Object value) throws HibernateException { | |
return value; | |
} | |
@Override | |
public boolean isMutable() { | |
return false; | |
} | |
@Override | |
public Serializable disassemble(Object value) throws HibernateException { | |
return (Serializable) value; | |
} | |
@Override | |
public Object assemble(Serializable cached, Object owner) | |
throws HibernateException { | |
return cached; | |
} | |
@Override | |
public Object replace(Object original, Object target, Object owner) | |
throws HibernateException { | |
return original; | |
} | |
@Override | |
public void setParameterValues(Properties parameters) { | |
// Initialize Method | |
initBasicType(); | |
initPreparedStatementSetter(); | |
} | |
@Override | |
public String objectToSQLString(Object value) { | |
return '\'' + ((Enum<?>) value).name() + '\''; | |
} | |
@Override | |
public String toXMLString(Object value) { | |
return ((Enum<?>) value).name(); | |
} | |
@Override | |
public Object fromXMLString(String xmlValue) { | |
// TODO | |
throw new IllegalAccessError(); | |
// return Enum.valueOf(, xmlValue); | |
} | |
protected void initBasicType() { | |
// 面倒だけど仕方ない・・・ | |
switch (getSqlType()) { | |
case Types.VARCHAR: | |
basicType = StringType.INSTANCE; | |
break; | |
case Types.INTEGER: | |
basicType = IntegerType.INSTANCE; | |
break; | |
default: | |
break; | |
} | |
} | |
protected void initPreparedStatementSetter() { | |
// TODO | |
switch (getSqlType()) { | |
case Types.VARCHAR: | |
psSetter = new StringPreparedStatementSetter(); | |
break; | |
case Types.INTEGER: | |
psSetter = new IntPreparedStatementSetter(); | |
default: | |
break; | |
} | |
} | |
private static interface PreparedStatementSetter { | |
void set(PreparedStatement st, Object value, int index) | |
throws SQLException; | |
} | |
private static class StringPreparedStatementSetter implements | |
PreparedStatementSetter { | |
@Override | |
public void set(PreparedStatement st, Object value, int index) { | |
try { | |
st.setString(index, (String) value); | |
} catch (SQLException e) { | |
} | |
} | |
} | |
private static class IntPreparedStatementSetter implements | |
PreparedStatementSetter { | |
@Override | |
public void set(PreparedStatement st, Object value, int index) { | |
try { | |
st.setInt(index, (Integer) value); | |
} catch (SQLException e) { | |
} | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package sample; | |
public enum Fuga { | |
A("a"), B("b"), C("c"); | |
private String code; | |
private Fuga(String code) { | |
this.code = code; | |
} | |
public static Fuga create(String code) { | |
if (code == null) { | |
return null; | |
} | |
for (Fuga enumValue : values()) { | |
if (enumValue.code.equals(code)) { | |
return enumValue; | |
} | |
} | |
return null; | |
} | |
public static class FugaEnumType extends AbstractEnumUserType<Fuga, String> { | |
@Override | |
protected Class<Fuga> getEnumClass() { | |
return Fuga.class; | |
} | |
@Override | |
protected Class<String> getValueClass() { | |
return String.class; | |
} | |
@Override | |
protected Fuga convertEnum(String rawValue) { | |
return create(rawValue); | |
} | |
@Override | |
protected String convertSqlValue(Fuga enumValue) { | |
return (enumValue == null) ? null : enumValue.code; | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package sample; | |
import javax.persistence.Column; | |
import javax.persistence.Entity; | |
import javax.persistence.Id; | |
import javax.persistence.Table; | |
import org.hibernate.annotations.Type; | |
@Entity | |
@Table(name = "hoge") | |
public class Hoge { | |
@Id | |
private String hogeId; | |
@Column(name = "fuga") | |
@Type(type = "sample.Fuga$FugaEnumType") | |
private Fuga fuga; | |
public Hoge(String hogeId, Fuga fuga) { | |
super(); | |
this.hogeId = hogeId; | |
this.fuga = fuga; | |
} | |
public Hoge() { | |
} | |
public String getHogeId() { | |
return hogeId; | |
} | |
public void setHogeId(String hogeId) { | |
this.hogeId = hogeId; | |
} | |
public Fuga getFuga() { | |
return fuga; | |
} | |
public void setFuga(Fuga fuga) { | |
this.fuga = fuga; | |
} | |
@Override | |
public String toString() { | |
return "Hoge [hogeId=" + hogeId + ", fuga=" + fuga + "]"; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment