锁定老帖子 主题:在hibernate中如何实现枚举?
该帖已经被评为精华帖
|
|
---|---|
作者 | 正文 |
发表时间:2004-11-19
robbin 写道 试过了,确实如此。这也算一个最佳实践了吧。我也多学了点东西。
但是不太明白为什么PersistentEnum被deprecated,并且这个接口的语意也不完整,缺了一个 public static fromInt(int code); 方法。不过Javadoc却给了出来。并且还说明要被移到2.2中(Hibernate3)。没有看过3的源码,不清楚有什么改进没有。 好像是这么回事: PersistentEnum的文档中要求实现 引用 /**
* Implementors of <tt>PersistentEnum</tt> are enumerated types persisted to * the database as <tt>SMALLINT</tt>s. As well as implementing <tt>toInt()</tt>, * a <tt>PersistentEnum</tt> must also provide a static method with the * signature:<br> * <br> * <tt>public static PersistentEnum fromInt(int i)</tt> * * @author Gavin King * @deprecated Support for PersistentEnums will be removed in 2.2 */ 但是,Interface中不让定义static方法。因此,只能要求用户在具体类中填写该方法。在PersistentEnumType中使用反射来执行fromInt()方法。 robbin 写道 并且还说明要被移到2.2中(Hibernate3)。
2.1.6 PersistentEnum源码中说明: 引用 @deprecated Support for PersistentEnums will be removed in 2.2
我个人的理解是“在2.2中会被删掉”,好像不是“要被移到2.2中”。 后续版本会不会支持PersistentEnums,对我很重要。怎么办呢?但愿是我理解错了,是“要被移到2.2中”。可是,那又何必标识“deprecated”? (发帖子时的“预览”还是不好用?) 顺便贴出PersistentEnumType中有关fromInt()处理的代码: 构造方法中,获取fromInt()的method。 public PersistentEnumType(Class enumClass); throws MappingException { this.enumClass = enumClass; try { method = enumClass.getDeclaredMethod("fromInt", INTEGER_ARG);; if ( !ReflectHelper.isPublic(enumClass, method); ); method.setAccessible(true);; } catch (NoSuchMethodException nme); { throw new MappingException("PersistentEnum class did not implement fromInt(int);: " + enumClass.getName(); );; } } getInstance()中执行该method,传递一个整数。 public Object getInstance(Integer code); throws HibernateException { try { return method.invoke( null, new Object[] { code } );; } catch (IllegalArgumentException iae); { throw new AssertionFailure("Could not invoke fromInt(); from PersistentEnumType", iae);; } catch (InvocationTargetException ite); { throw new HibernateException( "InvocationTargetException occurred inside fromInt();", ite );; } catch (IllegalAccessException iae); { throw new HibernateException( "IllegalAccessException occurred calling fromInt();", iae );; } } get()中执行getInstance()。 public Object get(ResultSet rs, String name); throws HibernateException, SQLException { int code = rs.getInt(name);; if ( rs.wasNull(); ); { return null; } else { return getInstance( new Integer(code); );; } } |
|
返回顶楼 | |
发表时间:2004-11-19
哦,没有注意“厌倦发呆”最后的帖子:
厌倦发呆 写道 All that is required to use this enum scheme is to import the following four classes into your project. public abstract class PersistentCharacterEnum extends PersistentEnum public abstract class PersistentIntegerEnum extends PersistentEnum public abstract class PersistentStringEnum extends PersistentEnum abstract class PersistentEnum implements Comparable, Serializable, UserType 这么说,PersistentEnum 被改成抽象类,而不再是接口。而且是包内私有,这样我们只能使用PersistentIntegerEnum 等这样的类。 这样的话,也可以接受。 谢谢! |
|
返回顶楼 | |
发表时间:2005-01-13
看了3.0beta1的代码,
public abstract class PersistentCharacterEnum extends PersistentEnum public abstract class PersistentIntegerEnum extends PersistentEnum public abstract class PersistentStringEnum extends PersistentEnum abstract class PersistentEnum implements Comparable, Serializable, UserType 这几个class在哪里啊?难道要自己实现吗?不太明白啊. |
|
返回顶楼 | |
发表时间:2005-01-13
抱歉,当时Hibernate还只是alpha版,这个PersistentEnum其实是一种解决方案,误导大家了。
http://www.hibernate.org/203.html |
|
返回顶楼 | |
发表时间:2005-01-13
总之是要自己coding了,Hibernate就不再内建支持了.
|
|
返回顶楼 | |
发表时间:2005-01-19
另外构造函数都要public才行,不爽啊,明显应该是private的嘛.
|
|
返回顶楼 | |
发表时间:2006-01-21
derivation: http://www.hibernate.org/172.html
UserType for persisting a Typesafe Enumeration with a VARCHAR column Use this Typesafe Enumeration class in your domain model as a simple property type (e.g. of the Comment class in a forum): public class Rating implements Serializable { private String name; public static final Rating EXCELLENT = new Rating("Excellent");; public static final Rating OK = new Rating("OK");; public static final Rating LOW = new Rating("Low");; private static final Map INSTANCES = new HashMap();; static { INSTANCES.put(EXCELLENT.toString();, EXCELLENT);; INSTANCES.put(OK.toString();, OK);; INSTANCES.put(LOW.toString();, LOW);; } private Rating(String name); { this.name=name; } public String toString(); { return name; } private Object readResolve(); { return getInstance(name);; } public static Rating getInstance(String name); { return (Rating);INSTANCES.get(name);; } } Next, write the Hibernate custom mapping type: public class RatingUserType implements UserType { private static final int[] SQL_TYPES = {Types.VARCHAR}; public int[] sqlTypes(); { return SQL_TYPES; } public Class returnedClass(); { return Rating.class; } public boolean equals(Object x, Object y); { return x == y; } public Object deepCopy(Object value); { return value; } public boolean isMutable(); { return false; } public Object nullSafeGet(ResultSet resultSet, String[] names, Object owner); throws HibernateException, SQLException { String name = resultSet.getString(names[0]);; return resultSet.wasNull(); ? null : Rating.getInstance(name);; } public void nullSafeSet(PreparedStatement statement, Object value, int index); throws HibernateException, SQLException { if (value == null); { statement.setNull(index, Types.VARCHAR);; } else { statement.setString(index, value.toString(););; } } } Finally, in your mapping files, bind it all together: <hibernate-mapping package="org.hibernate.auction.model"> <class name="Comment" table="COMMENTS" lazy="true"> <!-- Common id property. --> <id name="id" type="long" column="COMMENT_ID" unsaved-value="null"> <generator class="native"/> </id> <!-- Simple property. --> <property name="rating" column="RATING" type="org.hibernate.auction.persistence.RatingUserType" not-null="true" update="false"/> ... </class> </hibernate-mapping> You may also use your Rating enumerated type in Hibernate queries: Query q = session.createQuery("from Comment c where c.rating = :rating");; q.setParameter("rating", Rating.LOW, Hibernate.custom(RatingUserType.class););; This is all there is to know about it. You may enhance this strategy with a generic UserType implementation, that knows how to persist different Typesafe Enumerations, this is described here. The examples and domain model you have just seen can be found in Hibernate in Action. Christian |
|
返回顶楼 | |