Personalizando tipos do hibernate implementando UserType ou extendendo hibernate.type.Timestamp

OLá pessoal, estamos desenvolvendo uma aplicação java + adobe flex, como todo mundo sabe trabalhar com formatação de datas no client(flex) ou javascritp e bem trabalhoso e propenso a erros. Então o pessoal aqui sugeriu que tivessemos um tipo personalizado do hibernate que resolva estas formatações, então quando tivermos um campo (tymestamp) no banco de dados, teremos um atributodo tipo string no bean (java), pra gravar no banco pegamos a string (10/10/2010) por exemplo, instanciamos uma data e salvamos no banco, quando acontece uma consulta gostaria de pegar do banco o tymestamp, formatar e mandar a string pronta pra camada de apresentação (flex).

então dei uma olhada na documentação do hibernate e tentei a seguinte implemetação…

package com.atual.datamodel.util.tipos;

import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

public class DataFormatada extends org.hibernate.type.TimestampType {

@Override
public Object get(ResultSet rs, String name) throws SQLException {
	DateFormat f = new SimpleDateFormat("dd/MM/yyyy");

	return f.format(super.get(rs, name));

}

@Override
public void set(PreparedStatement st, Object value, int index) throws SQLException {


	try {
		super.set(st, parseDate(value.toString()), index);
	} catch (Exception e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	}
}

@Override
public String toString(Object value) {
	DateFormat f = new SimpleDateFormat("dd/MM/yyyy");
	return f.format(value.toString());
}

/**
 * Converte uma String para um objeto java.sql.Date. Caso a String seja
 * vazia ou nula, retorna null ? para facilitar em casos onde formulários
 * podem ter campos de datas vazios.
 * 
 * @param strData
 *            String no formato dd/MM/yyyy a ser formatada
 * @return java.sql.Date
 * @throws Exception
 *             Caso a String esteja no formato errado
 */
private Date parseDate(String strData) throws Exception {
	if (strData == null || strData.equals("")) {
		return null;
	}
	Date date = null;
	try {
		DateFormat f = new SimpleDateFormat("dd/MM/yyyy");
		date = (java.util.Date) f.parse(strData);
	} catch (ParseException e) {
		throw new Exception("Data com formato inválido");
	}
	return date;
}

}

mas não tive sucesso …

o hibernate da erro…

log:

msg: java.lang.String cannot be cast to java.util.Date

to meio perdido, achei q seria simples, se alguém puder me ajudar…

também tentei criar um tipo escrevendo uma classe que implementa a interface UserType do hibernate, mas num tive sucesso…

OLá pessoal consegui resolver criando uma classe implementando UserType do hibernate…

segue fonte :

package com.atual.datamodel.util.tipos;

import java.io.Serializable;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.HashMap;

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

// referencias de documentação
//http://docs.jboss.org/hibernate/stable/core/reference/en/html_single/#mapping-types-custom
//https://www.hibernate.org/hib_docs/v3/api/org/hibernate/usertype/UserType.html

public class DataFlex implements UserType {

	@Override
	public Object assemble(Serializable arg0, Object arg1) throws HibernateException {
		return arg0;
	}

	@Override
	public Object deepCopy(Object arg0) throws HibernateException {
		return arg0;
	}

	@Override
	public Serializable disassemble(Object arg0) throws HibernateException {
		return (Serializable) arg0;
	}

	@Override
	public boolean equals(Object arg0, Object arg1) throws HibernateException {
		if (arg0 == arg1) {
			return true;
		}
		return false;
	}

	@Override
	public int hashCode(Object arg0) throws HibernateException {
		return arg0.hashCode();
	}

	@Override
	public boolean isMutable() {
		return false;
	}

	// banco --> memória
	@Override
	public Object nullSafeGet(ResultSet res, String[] names, Object arg2)
			throws HibernateException, SQLException {

		// Long value = resultSet.getLong(names[0]);

		Date data = res.getDate(names[0]);

		DateFormat f = new SimpleDateFormat("dd/MM/yyyy");

		return f.format(data);
	}

	// memória -->banco
	@Override
	public void nullSafeSet(PreparedStatement statement, Object value, int index)
			throws HibernateException, SQLException {
		if (value == null) {
			statement.setNull(index, Hibernate.TIMESTAMP.sqlType());
		} else {

			try {
				statement.setDate(index, parseDateSQL(value.toString()));
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}

	}

	@Override
	public Object replace(Object arg0, Object arg1, Object arg2) throws HibernateException {
		return arg0;
	}

	@Override
	public Class returnedClass() {
		// return null;
		return HashMap.class;
	}

	@Override
	public int[] sqlTypes() {
		return new int[] { Types.TIMESTAMP };
	}

	/**
	 * Converte uma String para um objeto java.sql.Date. Caso a String seja
	 * vazia ou nula, retorna null ? para facilitar em casos onde formulários
	 * podem ter campos de datas vazios.
	 * 
	 * @param strData
	 *            String no formato dd/MM/yyyy a ser formatada
	 * @return java.sql.Date
	 * @throws Exception
	 *             Caso a String esteja no formato errado
	 */
	private Date parseDate(String strData) throws Exception {
		if (strData == null || strData.equals("")) {
			return null;
		}
		Date date = null;
		try {
			DateFormat f = new SimpleDateFormat("dd/MM/yyyy");
			date = (java.util.Date) f.parse(strData);
		} catch (ParseException e) {
			throw new Exception("Data com formato inválido");
		}
		return date;
	}

	/**
	 * Converte uma String para um objeto java.sql.Date. Caso a String seja
	 * vazia ou nula, retorna null ? para facilitar em casos onde formulários
	 * podem ter campos de datas vazios.
	 * 
	 * @param strData
	 *            String no formato dd/MM/yyyy a ser formatada
	 * @return java.sql.Date
	 * @throws Exception
	 *             Caso a String esteja no formato errado
	 */
	public java.sql.Date parseDateSQL(String strData) throws Exception {
		if (strData == null || strData.equals("")) {
			return null;
		}
		Date date = null;
		try {

			DateFormat f = new SimpleDateFormat("dd/MM/yyyy");

			date = (java.util.Date) f.parse(strData);

		} catch (ParseException e) {
			throw new Exception("Data com formato inválido");
		} catch (Exception ex) {
			ex.printStackTrace();
		}
		return new java.sql.Date(date.getTime());
	}
}




e meu mapeamento no xml ficou assim…

<?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="com.atual.modelo.cadastro.feriado">
	<class name="Feriado" table="tblCADFeriado">
		<id name="seq" type="integer" column="Seq"> <generator class="increment"></generator> </id>
		<property name="dataFeriado" column="Data_feriado"  type="com.atual.datamodel.util.tipos.DataFlex" not-null="true" />
		<property name="descFeriado" column="Desc_feriado" type="string" length="50" not-null="true"/>
		<property name="tipoFeriado" column="Tipo_feriado" type="string" length="1" not-null="true"/>
		<many-to-one name="codMunicipio" column="Cod_municipio" lazy="false"
			foreign-key="FK_tblCADMunicipio_tblCADFeriado">
		</many-to-one>
	</class>
</hibernate-mapping>