Convierta float/int a Calendar en jpa hibernate SQL Server

I'm developing a Java project with JPA / Hibernate and SQL Server DB.

I got an existent db where date fields are stored as int and datetime as float.

Does anyone know how can I implement a transparent conversion to a Calendar type in my domain class?

I must calculate the date in getter and setter or there's a better way?

¡Gracias! Marco

preguntado el 28 de agosto de 12 a las 14:08

what do the integers mean? Is 1100 11am or is that 1100 seconds after 1970 or 1100 ms after 1970. more infor please -

Do you mean you have two different columns that represent date and time and those should be merged to a single Date class in the domain object? Could you give an example of how the date and time are stored? -

In Sql Server executing: select cast(0 as datetime) -> 1900-01-01 00:00:00.000 select cast(41148 as datetime) -> 2012-08-29 00:00:00.000 -

2 Respuestas

Here is my solution! Hope is useful for someone!

As suggested by Vikdor I've implemented UserType interface:

public class MyDate implements UserType{

    private final static int SECONDS_IN_A_DAY = 86400;

    public Object assemble(Serializable cached, Object owner) throws HibernateException {
        return cached;

    public Object deepCopy(Object value) throws HibernateException {
        if (value == null)
            return null;

        return value;

    public Serializable disassemble(Object value) throws HibernateException {
        return (Serializable)value;

    public boolean equals(Object x, Object y) throws HibernateException {
        return ObjectUtils.equals(x, y);

    public int hashCode(Object x) throws HibernateException {
         assert (x != null);
         return x.hashCode();

    public boolean isMutable() {
        return false;

    public Object nullSafeGet(ResultSet resultSet, String[] names, Object owner) throws HibernateException, SQLException {
        assert names.length == 1;

        final String value = (String) StringType.INSTANCE.get(resultSet, names[0]);
        if (value == null) return null;     
        final String daysValue = value.substring(0, value.indexOf("."));
            final String secondsValue = value.substring(value.indexOf("."));

            final Calendar calendar = Calendar.getInstance();
            calendar.set(Calendar.YEAR, 1900);
            calendar.setTime(DateUtils.truncate(calendar, Calendar.YEAR).getTime());

            calendar.add(Calendar.DATE, Integer.valueOf(daysValue));
            calendar.add(Calendar.SECOND, (int)(SECONDS_IN_A_DAY * Float.valueOf(secondsValue)));
            return calendar;
        }catch(Exception e){
            throw new HibernateException("Cannot convert DB value " +value);

     * Convert from date to float
    public void nullSafeSet(PreparedStatement preparedStatement, Object value, int index) throws HibernateException, SQLException {     
        final Calendar currentDate = (Calendar) value;
        final Calendar zeroDate = Calendar.getInstance();

        zeroDate.set(Calendar.YEAR, 1900);
        zeroDate.setTime(DateUtils.truncate(zeroDate, Calendar.YEAR).getTime());

        final Days days = Days.daysBetween(new DateTime(zeroDate), new DateTime(currentDate) );

        final Seconds seconds = Seconds.secondsBetween(new DateTime(DateUtils.truncate(currentDate, Calendar.DAY_OF_MONTH).getTime()), new DateTime(currentDate) );
        float finalValue = days.getDays() + ((float)seconds.getSeconds()/SECONDS_IN_A_DAY);

        preparedStatement.setFloat(index, finalValue);      

    public Object replace(Object original, Object target, Object owner) throws HibernateException {
        return original;

    public Class<Calendar> returnedClass() {
        return Calendar.class;

    public int[] sqlTypes() {
        return new int[]{


Respondido 29 ago 12, 11:08

Lo haría de la siguiente manera:

  1. Two classes, MyDate & MyDateTime each implementing the Hibernate UserType de la interfaz del.
  2. MyDate will read the integer date as String, assuming the integer is of the format 20120828. In the nullSafeGet() implementation, it will convert this string to a Joda DateTime or Java.util.Date usando el SimpleDateFormat class with format as "yyyyMMdd".
  3. MyDateTime will read the float as String, asumiendo el float is of the format 20120828.190800. In the nullSafeGet() implementation, it too will convert this string to a Joda Datetime or java.util.Date usando el SimpleDateFormat class with format as "yyyyMMdd.HHmmss".
  4. Programas de nullSafeSet() will format back the data using the same SimpleDateFormat in the respective classes.

Espero que esto ayude.

Respondido el 12 de diciembre de 16 a las 08:12

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.