Convierta float/int a Calendar en jpa hibernate SQL Server
Frecuentes
Visto 1,897 veces
2
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
2 Respuestas
2
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;
@Override
public Object assemble(Serializable cached, Object owner) throws HibernateException {
return cached;
}
@Override
public Object deepCopy(Object value) throws HibernateException {
if (value == null)
return null;
return value;
}
@Override
public Serializable disassemble(Object value) throws HibernateException {
return (Serializable)value;
}
@Override
public boolean equals(Object x, Object y) throws HibernateException {
return ObjectUtils.equals(x, y);
}
@Override
public int hashCode(Object x) throws HibernateException {
assert (x != null);
return x.hashCode();
}
@Override
public boolean isMutable() {
return false;
}
@Override
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;
try{
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);
}
}
@Override
/**
* 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);
}
@Override
public Object replace(Object original, Object target, Object owner) throws HibernateException {
return original;
}
@Override
public Class<Calendar> returnedClass() {
return Calendar.class;
}
@Override
public int[] sqlTypes() {
return new int[]{
FloatType.INSTANCE.sqlType()
};
}
}
Respondido 29 ago 12, 11:08
1
Lo haría de la siguiente manera:
- Two classes, MyDate & MyDateTime each implementing the Hibernate
UserType
de la interfaz del. - 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 orJava.util.Date
usando elSimpleDateFormat
class with format as "yyyyMMdd". - MyDateTime will read the
float
asString
, asumiendo elfloat
is of the format 20120828.190800. In thenullSafeGet()
implementation, it too will convert this string to a Joda Datetime orjava.util.Date
usando elSimpleDateFormat
class with format as "yyyyMMdd.HHmmss". - Programas de
nullSafeSet()
will format back the data using the sameSimpleDateFormat
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 java sql-server hibernate jpa or haz tu propia pregunta.
what do the integers mean? Is 1100 11am or is that 1100 seconds after 1970 or 1100 ms after 1970. more infor please - RNJ
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? - ThomasIn 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 - gipinani