java.lang.verifyError on hibernate specific usertype

后端 未结 2 1267
轻奢々
轻奢々 2020-12-19 05:58

We have been using the GenericEnumUserType for our extensible enumerations and our classes fail to load in JBoss 6, on a Hibernate 3.6+ container.

The following erro

相关标签:
2条回答
  • 2020-12-19 06:34

    Unfortunately @Enumerated does not work if you need to serialize based on something other than the Enum's ordinal or name. I've managed to find a solution (modified slightly from here).

    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.AbstractSingleColumnStandardBasicType;
    import org.hibernate.type.TypeResolver;
    import org.hibernate.usertype.ParameterizedType;
    import org.hibernate.usertype.UserType;
    
    public class GenericEnumUserType implements UserType, ParameterizedType {
    
        private Class<? extends Enum> enumClass;
        private Class<?> identifierType;
        private Method identifierMethod;
        private Method valueOfMethod;
        private static final String defaultIdentifierMethodName = "name";
        private static final String defaultValueOfMethodName = "valueOf";
        private AbstractSingleColumnStandardBasicType type;
        private int[] sqlTypes;
    
        @Override
        public void setParameterValues( Properties parameters )
        {
            String enumClassName = parameters.getProperty("enumClass");
            try
            {
                enumClass = Class.forName( enumClassName ).asSubclass( Enum.class );
            }
            catch (ClassNotFoundException exception) {
                throw new HibernateException("Enum class not found", exception);
            }
    
            String identifierMethodName = parameters.getProperty( "identifierMethod", defaultIdentifierMethodName );
    
            try
            {
                identifierMethod = enumClass.getMethod( identifierMethodName,
                                                        new Class[0]);
                identifierType = identifierMethod.getReturnType();
            }
            catch (Exception exception)
            {
                throw new HibernateException("Failed to optain identifier method",
                        exception);
            }
    
            TypeResolver tr = new TypeResolver();
            type = (AbstractSingleColumnStandardBasicType)tr.basic( identifierType.getName() );
            if (type == null)
            {
                throw new HibernateException( "Unsupported identifier type " + identifierType.getName() );
            }
            sqlTypes = new int[] { type.sqlType() };
    
            String valueOfMethodName = parameters.getProperty( "valueOfMethod",
                                                               defaultValueOfMethodName);
    
            try
            {
                valueOfMethod = enumClass.getMethod( valueOfMethodName,
                                                     new Class[] { identifierType } );
            }
            catch ( Exception exception )
            {
                throw new HibernateException( "Failed to optain valueOf method",
                                              exception);
            }
        }
    
        @Override
        public Class returnedClass()
        {
            return enumClass;
        }
    
        @Override
        public Object nullSafeGet( ResultSet rs, String[] names, Object owner )
            throws HibernateException, SQLException
        {
            Object identifier = type.get( rs, names[0] );
            try
            {
                return valueOfMethod.invoke( enumClass, new Object[] { identifier } );
            }
            catch ( Exception exception )
            {
                throw new HibernateException( "Exception while invoking valueOfMethod of enumeration class: ",
                                              exception);
            }
        }
    
        public void nullSafeSet( PreparedStatement st, Object value, int index )
            throws HibernateException, SQLException
        {
            try
            {
                Object identifier = value != null ? identifierMethod.invoke( value,
                                                                             new Object[0] ) : null;
                st.setObject( index, identifier );
            }
            catch ( Exception exception )
            {
                throw new HibernateException( "Exception while invoking identifierMethod of enumeration class: ",
                                              exception );
    
            }
        }
    
        @Override
        public int[] sqlTypes()
        {
            return sqlTypes;
        }
    
        @Override
        public Object assemble( Serializable cached, Object owner )
            throws HibernateException
        {
            return cached;
        }
    
        @Override
        public Object deepCopy( Object value )
            throws HibernateException
        {
            return value;
        }
    
        @Override
        public Serializable disassemble( Object value )
            throws HibernateException
        {
            return (Serializable) value;
        }
    
        @Override
        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;
        }
    }
    
    0 讨论(0)
  • 2020-12-19 06:44

    There's no TypeFactory.basic(String) in Hibernate 3.6 anymore. Compare the javadocs:

    http://docs.jboss.org/hibernate/core/3.6/javadocs/org/hibernate/type/TypeFactory.html http://docs.jboss.org/hibernate/core/3.3/api/org/hibernate/type/TypeFactory.html

    I think it's now time to move from a custom UserType to the standard @Enumerated :-)

    0 讨论(0)
提交回复
热议问题