All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.foreach.common.hibernate.util.HibernateEnum Maven / Gradle / Ivy

/*
 * Copyright 2014 the original author or authors
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.foreach.common.hibernate.util;

import org.hibernate.HibernateException;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.type.BasicType;
import org.hibernate.type.TypeFactory;
import org.hibernate.type.TypeResolver;
import org.hibernate.type.spi.TypeConfiguration;
import org.hibernate.usertype.ParameterizedType;
import org.hibernate.usertype.UserType;

import java.io.Serializable;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Properties;

/**
 * 

This class converts the string value from the resultset to Java Enum and vice versa.

*

* Usage Eg - To map a java enum object Role, define the following mapping in hbm file. *

 *     <typedef class="com.foreach.hibernate.enums.HibernateEnum" name="roleType">
 *          <param name="enumClassName">com.xxx.xxx.Role</param>
 *     </typedef>
 *  
*

*/ // Improvement: -Looks like this can be simplified for the end user using reflection, as in this example: // http://community.jboss.org/wiki/Java5StringValuedEnumUserType public class HibernateEnum implements UserType, ParameterizedType { private static final String DEFAULT_IDENTIFIER_METHOD_NAME = "getId"; private static final String DEFAULT_VALUE_OF_METHOD_NAME = "getById"; /* Sonar will bitch, because Hibernate will construct instances using a zero argument constructor and the method setParameterValues, so many instance variables remain null after construction. */ private Class enumClass; private Method identifierMethod; private Method valueOfMethod; private BasicType type; private int[] sqlTypes; public HibernateEnum() { // an empty constructor setting member variables to null to dodge sonar from reporting // "Variables not initialized inside constructor" this.enumClass = null; this.identifierMethod = null; this.valueOfMethod = null; this.type = null; this.sqlTypes = null; } public final void setParameterValues( Properties parameters ) { String enumClassName = parameters.getProperty( "enumClassName" ); Class identifierType; try { enumClass = Class.forName( enumClassName ).asSubclass( Enum.class ); } catch ( ClassNotFoundException cfne ) { throw new HibernateException( "Enum class not found", cfne ); } String identifierMethodName = parameters.getProperty( "identifierMethod", DEFAULT_IDENTIFIER_METHOD_NAME ); try { identifierMethod = enumClass.getMethod( identifierMethodName ); identifierType = identifierMethod.getReturnType(); } catch ( Exception e ) { throw new HibernateException( "Failed to obtain identifier method", e ); } type = new TypeConfiguration().getTypeResolver().basic( identifierType.getName() ); if ( type == null ) { throw new HibernateException( "Unsupported identifier type " + identifierType.getName() ); } sqlTypes = new int[] { type.sqlTypes(null)[0] }; String valueOfMethodName = parameters.getProperty( "valueOfMethod", DEFAULT_VALUE_OF_METHOD_NAME ); try { valueOfMethod = enumClass.getMethod( valueOfMethodName, identifierType ); } catch ( Exception e ) { throw new HibernateException( "Failed to obtain valueOf method", e ); } } public final Class returnedClass() { return enumClass; } @Override public final Object nullSafeGet( ResultSet rs, String[] names, SharedSessionContractImplementor session, Object owner ) throws SQLException { Object identifier = type.nullSafeGet( rs, names[0] ,session,owner); if ( rs.wasNull() ) { return null; } StringBuffer errorMsg = new StringBuffer( "Exception while invoking valueOf method \"" ); try { errorMsg.append( valueOfMethod.getName() ).append( "\" of " ).append( "enumeration class \"" ).append( enumClass ).append( '\"' ); return valueOfMethod.invoke( enumClass, identifier ); } catch ( IllegalAccessException exc ) { throw new HibernateException( errorMsg.toString(), exc ); } catch ( InvocationTargetException exc ) { throw new HibernateException( errorMsg.toString(), exc ); } } @Override public final void nullSafeSet( PreparedStatement st, Object value, int index, SharedSessionContractImplementor session ) throws SQLException { StringBuffer errorMsg = new StringBuffer( "Exception while invoking identifierMethod method \"" ); try { errorMsg.append( identifierMethod.getName() ).append( "\" of " ).append( "enumeration class \"" ).append( enumClass ).append( '\"' ); if ( value == null ) { st.setNull( index, type.sqlTypes(null)[0] ); } else { Object identifier = identifierMethod.invoke( value ); type.nullSafeSet( st, identifier, index, session ); } } catch ( IllegalAccessException | InvocationTargetException exc ) { throw new HibernateException( errorMsg.toString(), exc ); } } public final int[] sqlTypes() { return sqlTypes; } public final Object assemble( Serializable cached, Object owner ) { return cached; } public final Object deepCopy( Object value ) { return value; } public final Serializable disassemble( Object value ) { return (Serializable) value; } // Enum equallity IS pointer equality @SuppressWarnings("all") public final boolean equals( Object x, Object y ) { if ( x == null ) { return ( y == null ); } return x.equals( y ); } public final int hashCode( Object x ) { return x.hashCode(); } public final boolean isMutable() { return false; } public final Object replace( Object original, Object target, Object owner ) { return original; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy