使用hibernate将枚举存储在数据库中

时间:2013-01-02 21:59:58

标签: mysql hibernate enums java-7

我需要使用Hibernate存储一个对象,但是这个对象使用枚举。我可以存储,但是当我再次尝试检索它时,失败并出现此错误:“研究未映射[FROM Studies]”。 我在互联网上尝试了很多解决方案,但没有任何效果。我使用MySQL数据库

这是枚举:

public enum StudyStatus {

    Created("Created"), Started("Started"), Closed("Closed");

    private final String value;

    StudyStatus(String value){
        this.value = value;
    }



    public static StudyStatus fromValue(int value){
        for (StudyStatus status : values()) {  
            if (status.value.equals(value)) {  
                return status;  
            }  
        }  
        throw new IllegalArgumentException("Invalid status: " + value);  
    }

    public String toValue(){
        return value;
    }

}

这是EnumUserType类

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) {
        }
    }
}

}

包含枚举的类

import java.util.ArrayList;

import ateam.capi.common.enums.StudyStatus;

public class Study {

private String id;
private String name;
private StudyStatus status;
private ArrayList<User> pollsters;
private Questionnaire actualQuestionnaire;

public Questionnaire getActualQuestionnaire() {
    return actualQuestionnaire;
}

public void setActualQuestionnaire(Questionnaire actualQuestionnaire) {
    this.actualQuestionnaire = actualQuestionnaire;
}

public String getId() {
    return id;
}

public void setId(String id) {
    this.id = id;
}

public String getName() {
    return name;
}

public void setName(String name) {
    this.name = name;
}

public StudyStatus getStatus() {
    return status;
}

public void setStatus(StudyStatus status) {
    this.status = status;
}

public ArrayList<User> getPollsters() {
    return pollsters;
}

public void setPollsters(ArrayList<User> pollsters) {
    this.pollsters = pollsters;
}

}

这是用于映射Study类的XML

<hibernate-mapping package="ateam.capi.common.beans">
    <class name="Study" table="Studies">
        <id name="id" column="id"></id>
        <property name="name"/>
        <property name="status">
             <type name="ateam.capi.capipersistence.utils.EnumUserType">
                <param name="enumClassName">
                    ateam.capi.common.enums.StudyStatus
                </param>
             </type>
        </property>
    </class>
</hibernate-mapping>

学习DAO课程

import java.util.List;

import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.Transaction;

import ateam.capi.capipersistence.utils.HibernateUtil;
import ateam.capi.common.beans.Questionnaire;
import ateam.capi.common.beans.Study;

public class DAO_Study {

private Session session;
private Transaction tx;

public void saveStudy(Study study) throws HibernateException{
    try{
        initOperations();
        session.save(study);
        tx.commit();
    } catch (HibernateException ex){
        handleException(ex);
        throw ex;
    } finally{
        if (session!=null){
            session.close();
        }
    }
}

public void deleteStudy(Study study) throws HibernateException{ 
    try{ 
        initOperations(); 
        this.session.delete(study); 
        this.tx.commit(); 
    } catch (HibernateException ex){ 
        handleException(ex); 
        throw ex; 
    } finally{ 
        if (session!=null){
            session.close();
        } 
    }
}

public List<Study> getStudiesList() throws HibernateException{ 
    List<Study> studiesList = null;  
    try{ 
        initOperations(); 
        String hql = "FROM Studies";
        Query query = session.createQuery(hql);
        studiesList = query.list();
    } catch (HibernateException ex){ 
        handleException(ex); 
        throw ex; 
    } finally{ 
        if (session!=null){
            session.close();
        } 
    } 
    return studiesList; 
}

private void initOperations() throws HibernateException{
    HibernateUtil.createSession();
    this.session = HibernateUtil.getSessionFactory().openSession();
    this.tx = this.session.beginTransaction();
}

private void handleException(HibernateException ex) throws HibernateException{
    this.tx.rollback();
    System.out.println(ex.getStackTrace());
    throw ex;
}

}

我使用Java7和hibernate 4.1.8,我找到了其他解决方案,但在java7中不起作用

任何想法? 谢谢!

1 个答案:

答案 0 :(得分:2)

您的查询不应该是from study而不是from studies吗?研究表不是定义的实体。