Hibernate Books

All times are UTC - 5 hours [ DST ]



Post new topic Reply to topic  [ 6 posts ] 
Author Message
 Post subject: Dates and MySQL (how to save Millisecond?)
PostPosted: Thu Mar 19, 2009 2:54 pm 
Newbie

Joined: Fri Mar 06, 2009 11:22 am
Posts: 16
So I have come to the realization that when writing data to a table in MySQL my Dates have all their fractional pieces stripped. I had read that there is a way to work around this in Hibernate but have not yet seen a solution for how. Are there any resources detailing this?


Top
 Profile  
 
 Post subject:
PostPosted: Thu Mar 19, 2009 3:47 pm 
Beginner
Beginner

Joined: Wed Oct 03, 2007 4:10 am
Posts: 46
Please post your mapping for better understanding of your problem.


First, you can try to map the date property as timestamp.

<property name="dataModif" type="timestamp">
<column name="DATA_MODIF" sql-type="DATE"/>
</property>


you can omit sql-type="DATE"


Top
 Profile  
 
 Post subject:
PostPosted: Thu Mar 19, 2009 3:57 pm 
Newbie

Joined: Fri Mar 06, 2009 11:22 am
Posts: 16
I am not sure my config will provide any more information than what I have already provide.


Essentially I am doing this through annotations so I have no mapping. My problem is that when saving a Date from my Entity the fractional seconds are always dropped when going to MySQL. When using Derby I dont' have this problem since Derby has a millisecond resolution for times. I would like to know how to add a custom handler to tell Hibernate how to marshall this in and out properly instead of having the time truncated.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Mar 19, 2009 4:16 pm 
Beginner
Beginner

Joined: Wed Oct 03, 2007 4:10 am
Posts: 46
You can make your own custom type by implementing org.hibernate.usertype.UserType and
then using in your mappings or annotations.

good luck.


Top
 Profile  
 
 Post subject:
PostPosted: Fri Mar 27, 2009 10:10 am 
Newbie

Joined: Tue Jun 19, 2007 6:53 am
Posts: 7
Location: Hamburg, Germany
Hi,

I have the same problem. I managed to write a Hibernate UserType class (s. http://hibernate.org/272.html) that fetches the bigint value and returns a date object. Times have to be stored as milliseconds since 1970-01-01.

The mapping file has to contain the following:
Code:
    <typedef name="myTypeDef" class='com.example.DateUserType'>
        <param name="myClassName">com.example.DateUserType</param>
    </typedef>

(snip)

        <property
            name="evalDatetime"
            type="myTypeDef"
            update="true"
            insert="true"
            column="eval_datetime"
        />



This finally works, but which annotations can I use to let Ant create the mapping file? The annotations already exist for the other fields, but I don´t know how to use them for this UserType.

I tried:
Code:
   /**
    * @hibernate.property
    * column="eval_datetime"
    * @Type(type = "com.example.DateUserType",
    *        parameters = {@Parameter(
    *                      name = "myClassName",
    *                      value = "com.example.DateUserType") })


as seen here: http://hibernate.org/272.529.html


Hope anyone can help.

Lars


Top
 Profile  
 
 Post subject:
PostPosted: Thu Apr 02, 2009 7:07 am 
Newbie

Joined: Tue Jun 19, 2007 6:53 am
Posts: 7
Location: Hamburg, Germany
Ok, problem solved: I had to switch from xdoclet1 to EJB annotations (which was quite a hard fight).

Here is the complete solution for all others that have this problem.

The UserDateType class:
Code:
package de.xxx.client.hibernate;

import java.io.Serializable;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
import java.util.*;

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

/**
* Is used to fetch bigint values from the DB and to transform it into dates that contain
* milliseconds. MySQL would loose milliseconds when using a datetime field.
*
* Copied and adapted from http://hibernate.org/272.html
*/
public class DateUserType implements UserType, ParameterizedType {

   private Class<?> clazz = null;

   public void setParameterValues(Properties params) {
      String myClassName = params.getProperty("myClassName");
      if (myClassName == null) {
         throw new MappingException("myClassName parameter not specified");
      }

      try {
         this.clazz = Class.forName(myClassName);
      } catch (java.lang.ClassNotFoundException e) {
         throw new MappingException("Class " + myClassName + " not found", e);
      }
   }

   private static final int[] SQL_TYPES = { Types.BIGINT };

   public int[] sqlTypes() {
      return SQL_TYPES;
   }

   public Class<?> returnedClass() {
      return clazz;
   }

   public Date nullSafeGet(ResultSet resultSet, String[] names, Object owner) throws HibernateException, SQLException {
      Date result = null;
      if (!resultSet.wasNull()) {
         long value = resultSet.getLong(names[0]);
         result = new Date(value);
      } else {
         result = new Date(0);
      }

      return result;
   }

   public void nullSafeSet(PreparedStatement preparedStatement, Object value, int index) throws HibernateException, SQLException {
      System.out.println("not implemented");
//      if (value == null) {
//         preparedStatement.setNull(index, Types.BIGINT);
//      } else {
//         preparedStatement.setString(index, value.name());
//      }
   }

   public Object deepCopy(Object value) throws HibernateException {
      return value;
   }

   public boolean isMutable() {
      return false;
   }

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

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

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

   public int hashCode(Object x) throws HibernateException {
      return x.hashCode();
   }

   public boolean equals(Object x, Object y) throws HibernateException {
      if (x == y) return true;
      if (null == x || null == y) return false;
      return x.equals(y);
   }
}



Part of the code from the bean class:
Code:
private Date evalDatetime = null;

/**
* @return the datetime on which the evaluation happened
*/
@Column(name="evalDatetime")
@Type(type = "de.xxx.client.hibernate.DateUserType",
      parameters = { @Parameter(
            name = "myClassName",
            value = "de.xxx.client.hibernate.DateUserType") })
public Calendar getEvalDatetime() {
   GregorianCalendar cal = new GregorianCalendar();
   cal.setTime(evalDatetime);
   
   return cal;
}


Configuration is done via addAnnotatedClass() (details: http://www.hibernate.org/hib_docs/annot ... /ch01.html)


I hope this helps some other guys a lot of time =)


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 6 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.