Over a million developers have joined DZone.

Hibernate UserTypeSupport

DZone's Guide to

Hibernate UserTypeSupport

Free Resource
A base class for Hibernate UserTypes, that handles absolutely everything except the conversion between JDBC value and mapped entity value.

package net.andrewspencer.util.hibernate;

import java.io.Serializable;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;

import org.hibernate.HibernateException;
import org.hibernate.usertype.UserType;


* Base class for Hibernate UserTypes. *


* This class handles all the mechanics except for the conversion itself * between JDBC and entity values, for which you provide an instance of JdbcEntityConverter. * * @author Andrew Spencer */ public class UserTypeSupport implements UserType { /** * Conversion strategy between the value seen by JDBC and the representation * used in the entity class. * * @param * The class of the property as declared in the entity * @param * The class of the value returned by or passed to JDBC * (JDBC must be able to convert between this class and * the SQL type; the JDBC specs list the available conversions). * @author spencera */ public interface JdbcEntityConverter { /** * Converts the JDBC value to the value mapped and exposed by the entity * * @param value * the value returned by JDBC (guaranteed non null) * @return the value to be set in the entity * @throws SQLException */ MappedClass jdbcToEntity(JdbcClass databaseValue) throws SQLException; /** * @param objectValue * the value present in the entity (guaranteed non null) * @return the value to pass to JDBC */ Object entityToJdbc(MappedClass objectValue); } private Class mappedClass = null; private Class jdbcClass = null; private int sqlType; private String dbTypeName = null; private JdbcEntityConverter jdbcEntityConverter; /** * @param mappedClass * The class of the property defined on the entity * @param jdbcClass * The class of the value passed to or returned from JDBC * @param sqlType * The SQL type: one of the constants defined by java.sql.Types * @param jdbcEntityConverter * The conversion strategy */ protected UserTypeSupport(final Class mappedClass, final Class jdbcClass, final int sqlType, final JdbcEntityConverter databaseRepresentation) { this.mappedClass = mappedClass; this.jdbcClass = jdbcClass; this.sqlType = sqlType; this.jdbcEntityConverter = databaseRepresentation; } public int[] sqlTypes() { return new int[] {sqlType}; } public Class returnedClass() { return mappedClass; } public Object nullSafeGet(final ResultSet resultSet, final String[] names, final Object owner) throws HibernateException, SQLException { if (resultSet.wasNull()) { return null; } String columnName = names[0]; int columnIndex = resultSet.findColumn(columnName); @SuppressWarnings("unchecked") // This overloading of getObject() ensures returned value is of correct type JdbcClass dbValue = (JdbcClass) resultSet.getObject(columnIndex, mapDbTypeNameToJdbcType(resultSet, columnIndex)); // exception on preceding line? Ensure native SQL type is indeed convertible into return jdbcEntityConverter.jdbcToEntity(dbValue); } private Map > mapDbTypeNameToJdbcType(final ResultSet resultSet, int columnIndex) throws SQLException { Map > dbTypeNameToJdbcType = new HashMap >(); // map only for the type we are interested in returning dbTypeNameToJdbcType.put(retrieveColumnTypeName(resultSet, columnIndex), jdbcClass); return dbTypeNameToJdbcType; } private synchronized String retrieveColumnTypeName(final ResultSet resultSet, final int columnIndex) throws SQLException { if (dbTypeName == null) { dbTypeName = resultSet.getMetaData().getColumnTypeName(columnIndex); } return dbTypeName; } public void nullSafeSet(final PreparedStatement preparedStatement, final Object value, final int index) throws HibernateException, SQLException { if (null == value) { preparedStatement.setNull(index, sqlType); } else { @SuppressWarnings("unchecked") // type must be if Hibernate mapping is correct MappedClass valueCast = (MappedClass) value; preparedStatement.setObject(index, jdbcEntityConverter.entityToJdbc(valueCast), sqlType); } } public Object deepCopy(final Object value) throws HibernateException { return value; } public boolean isMutable() { return false; } public Object assemble(final Serializable cached, final Object owner) throws HibernateException { return cached; } public Serializable disassemble(final Object value) throws HibernateException { return (Serializable) value; } public Object replace(final Object original, final Object target, final Object owner) throws HibernateException { return original; } public int hashCode(final Object x) throws HibernateException { return x.hashCode(); } public boolean equals(final Object x, final Object y) throws HibernateException { if (x == y) { return true; } if (null == x || null == y) { return false; } return x.equals(y); } }


Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}