Friday, September 01, 2006
Enum Type in Hibernate Mapping
參考這篇「Java 5 EnumUserType」文章
就直接用昨天Generic CRUD DAO程式來改吧!
EnumUserType.java
以這個EnumUserType class來轉接Enum Type
package util;
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.usertype.EnhancedUserType;
import org.hibernate.usertype.ParameterizedType;
/**
* @author Gavin King
*/
public class EnumUserType implements EnhancedUserType, ParameterizedType {
private Class<Enum> enumClass;
public void setParameterValues(Properties parameters) {
String enumClassName = parameters.getProperty("enumClassName");
try {
enumClass = (Class<Enum>) Class.forName(enumClassName);
} catch (ClassNotFoundException cnfe) {
throw new HibernateException("Enum class not found", cnfe);
}
}
public Object assemble(Serializable cached, Object owner)
throws HibernateException {
return cached;
}
public Object deepCopy(Object value) throws HibernateException {
return value;
}
public Serializable disassemble(Object value) throws HibernateException {
return (Enum) value;
}
public boolean equals(Object x, Object y) throws HibernateException {
return x == y;
}
public int hashCode(Object x) throws HibernateException {
return x.hashCode();
}
public boolean isMutable() {
return false;
}
public Object nullSafeGet(ResultSet rs, String[] names, Object owner)
throws HibernateException, SQLException {
String name = rs.getString(names[0]);
return rs.wasNull() ? null : Enum.valueOf(enumClass, name);
}
public void nullSafeSet(PreparedStatement st, Object value, int index)
throws HibernateException, SQLException {
if (value == null) {
st.setNull(index, Types.VARCHAR);
} else {
st.setString(index, ((Enum) value).name());
}
}
public Object replace(Object original, Object target, Object owner)
throws HibernateException {
return original;
}
public Class returnedClass() {
return enumClass;
}
public int[] sqlTypes() {
return new int[] { Types.VARCHAR };
}
public Object fromXMLString(String xmlValue) {
return Enum.valueOf(enumClass, xmlValue);
}
public String objectToSQLString(Object value) {
return '\'' + ((Enum) value).name() + '\'';
}
public String toXMLString(Object value) {
return ((Enum) value).name();
}
}
Person.java
加入一個Gender enum type
package genericdaotest.domain;
import java.io.Serializable;
public class Person implements Serializable {
private Long id;
private String name;
private Gender gender;
private Integer weight;
public Person(String name, Gender gender, Integer weight) {
this.name = name;
this.gender = gender;
this.weight = weight;
}
// Default constructor needed by Hibernate
protected Person() {
}
public Long getId() {
return id;
}
private void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
private void setName(String name) {
this.name = name;
}
public Gender getGender() {
return gender;
}
public void setGender(Gender gender) {
this.gender = gender;
}
public Integer getWeight() {
return weight;
}
public void setWeight(Integer weight) {
this.weight = weight;
}
}
Gender.java
package genericdaotest.domain;
public enum Gender {
MALE, FEMALE
}
Person.hbm.xml
修改mapping檔
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="genericdaotest.domain">
<class name="Person">
<id name="id">
<generator class="native"></generator>
</id>
<property name="name" update="false" />
<property name="gender">
<type name="util.EnumUserType">
<param name="enumClassName">
genericdaotest.domain.Gender
</param>
</type>
</property>
<property name="weight" />
</class>
</hibernate-mapping>
PersonDaoTest.java
修改test case
package genericdaotest;
import genericdao.GenericDao;
import genericdaotest.domain.Gender;
import genericdaotest.domain.Person;
import junit.framework.TestCase;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.orm.hibernate3.SessionFactoryUtils;
import org.springframework.orm.hibernate3.SessionHolder;
import org.springframework.transaction.support.TransactionSynchronizationManager;
/**
* Simple test of the PersonDao
*/
public class PersonDaoTest extends TestCase {
private ApplicationContext factory;
public PersonDaoTest(String s) {
super(s);
factory = new ClassPathXmlApplicationContext("my-test.xml");
}
public void testCrud() throws Exception {
// Create
GenericDao personDao = (GenericDao) factory.getBean("personDao");
Person createPerson = new Person("Mellqvist", Gender.MALE, 88);
personDao.create(createPerson);
assertNotNull(createPerson.getId());
Long id = createPerson.getId();
restartSession();
// Read
Person foundPerson = (Person) personDao.read(id);
assertEquals(createPerson.getGender(), foundPerson.getGender());
restartSession();
// Update
Gender updateGender = Gender.FEMALE;
foundPerson.setGender(updateGender);
personDao.update(foundPerson);
Person updatedPerson = (Person) personDao.read(id);
assertEquals(updateGender, updatedPerson.getGender());
restartSession();
// Delete
personDao.delete(updatedPerson);
restartSession();
assertNull(personDao.read(id));
}
protected void setUp() throws Exception {
openSession();
}
protected void tearDown() throws Exception {
closeSession();
}
private void openSession() {
SessionFactory sessionFactory = getSessionFactory();
Session session = SessionFactoryUtils.getSession(sessionFactory, true);
TransactionSynchronizationManager.bindResource(sessionFactory,
new SessionHolder(session));
}
private void closeSession() {
SessionFactory sessionFactory = getSessionFactory();
SessionHolder sessionHolder = (SessionHolder) TransactionSynchronizationManager
.unbindResource(sessionFactory);
sessionHolder.getSession().flush();
sessionHolder.getSession().close();
SessionFactoryUtils.releaseSession(sessionHolder.getSession(),
sessionFactory);
}
private void restartSession() {
closeSession();
openSession();
}
private SessionFactory getSessionFactory() {
return (SessionFactory) factory.getBean("sessionFactory");
}
}




