Hi Myk,
Thanks for the pointers. I followed this process and came up with the following CompositeType to achieve this goal - figure it might be useful for someone else -
Code:
package dao.hibernate;
import java.io.Serializable;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
import java.util.Calendar;
import net.sf.hibernate.CompositeUserType;
import net.sf.hibernate.Hibernate;
import net.sf.hibernate.HibernateException;
import net.sf.hibernate.engine.SessionImplementor;
import net.sf.hibernate.type.Type;
public class DateTimeCombined implements CompositeUserType {
private static final int[] TYPES = {Types.DATE, Types.TIME};
public int[] sqlTypes() {
return TYPES;
}
public Class returnedClass() {
return java.util.Date.class;
}
public boolean equals(Object x, Object y) {
if(x == y) return true;
if((x == null) || (y == null)) return false;
return x.equals(y);
}
public Object deepCopy(Object x) {
if (x==null) return null;
return new java.util.Date(((java.util.Date)x).getTime());
}
public boolean isMutable() { return true; }
public Object nullSafeGet(ResultSet rs, String[] names, SessionImplementor session, Object owner) throws HibernateException, SQLException {
java.sql.Date date = (java.sql.Date)Hibernate.DATE.nullSafeGet(rs, names[0]);
java.sql.Time time = (java.sql.Time)Hibernate.TIME.nullSafeGet(rs, names[1]);
long timeMS = 0;
if(time != null) {
Calendar cal = Calendar.getInstance();
cal.setTime(time);
timeMS += cal.get(Calendar.HOUR_OF_DAY) * 3600000 + cal.get(Calendar.MINUTE) * 60000 + cal.get(Calendar.SECOND) * 1000;
}
if(date == null && time == null) return null;
if(date == null) return new java.util.Date(timeMS);
return new java.util.Date(date.getTime() + timeMS);
}
public void nullSafeSet(PreparedStatement st, Object value, int index, SessionImplementor session) throws HibernateException, SQLException {
java.util.Date dateTime = (value==null) ? new java.util.Date() : (java.util.Date)value;
Hibernate.DATE.nullSafeSet(st, new java.sql.Date(dateTime.getTime()), index);
Hibernate.TIME.nullSafeSet(st, new java.sql.Time(dateTime.getTime()), index+1);
}
public String[] getPropertyNames() {
return new String[] {"d", "t" };
}
public Type[] getPropertyTypes() {
return new Type[] {Hibernate.DATE, Hibernate.TIME};
}
public Object getPropertyValue(Object component, int property) {
if(property == 0) return new java.sql.Date(((java.util.Date)component).getTime());
if(property == 1) return new java.sql.Time(((java.util.Date)component).getTime());
return null;
}
public void setPropertyValue(Object component, int property, Object value) {
java.util.Date dateTime = (java.util.Date)component;
if(property == 0) dateTime.setTime(dateTime.getTime() + ((java.sql.Date)value).getTime());
else if(property == 1) dateTime.setTime(dateTime.getTime() + ((java.sql.Time)value).getTime());
}
public Object assemble(Serializable cached, SessionImplementor session, Object owner) {
return deepCopy(cached);
}
public Serializable disassemble(Object value, SessionImplementor session) {
return (Serializable) deepCopy(value);
}
}
]
The value i got back from java.sql.Date.getTime() was what I expected, but the value I got from the java.sql.Time.getTime() wasn't - so I ended up constructing the ms value for the time field. I wouldn't be surprised if I missed something in there, but it seems to read and write the fields accruately.
The mapping definition for this field is as follows -
Code:
<property name="modified" type="dao.hibernate.DateTimeCombined">
<column name="CDDATE" sql-type="date" not-null="true"/>
<column name="CDTIME" sql-type="time" not-null="true"/>
</property>
Anyway, thanks again,
Colin