Hibernate version: 3.2.4.sp1
Mapping documents: Using XML
Name and version of the database I am using: Oracle XE/10G
Stemming from my earlier post
http://forum.hibernate.org/viewtopic.php?t=985706, I did some further testing and found some interesting quirks
Code:
2008-04-10 19:11:20,369 INFO [net.tp.util.CriterionFactoryForFilterTypes] - <From the criterion factory 1196658000000 and pattern yyyy-MM-dd>
The log line above shows the date (in milliseconds) that the user enters as well as the date pattern
Code:
2008-04-10 19:10:30,947 INFO [net.tp.util.DateUserType] - < The date coming back 1196658000000>
The log line above shows the date (in milliseconds) that DateUserType -- an implementation of UserType -- gets from the db but according to Hibernate the 2 dates do not match as a matter of fact anytime I run Criterion query with dates I get back absolutely no results and no error is thrown.
Code:
2008-04-10 19:11:20,447 INFO [net.tp.biz.FilterToHibernateMapper] - <Criteria info CriteriaImpl(net.tp.domain.HibernateRequestObject:this[][dateCreated=Mon Dec 03 00:00:00 EST 2007, ()])>
The above log line is the Criteria.toString() method before it is executed by Criteria.list(). This shows what date the user entered and the property I am querying.
Code:
2008-04-10 19:17:35,322 INFO [net.tp.DateUserType] - < The date coming back Mon Dec 03 00:00:00 EST 2007>
The above log line is the date in the UserType implementation; I see nothing wrong with the dates, they look identical so why is it not returning a result, I am just baffled and frustrated.
Can anyone shed some light please??
Below is my implementation of UserType, modified from my earlier post
Code:
import java.io.Serializable;
import org.hibernate.usertype.UserType;
import org.hibernate.Hibernate;
import org.hibernate.HibernateException;
import java.util.Date;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.sql.Types;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import org.apache.log4j.Logger;
public class DateUserType implements UserType
{
private static final int[] SQL_TYPES = new int[] { Types.TIMESTAMP };
private static final Logger log = Logger.getLogger(DateUserType.class);
private static final DateFormat shortDate=new SimpleDateFormat("yyyy-MM-dd");
public DateUserType(){
super();
}
public int[] sqlTypes() {
return SQL_TYPES;
}
public Class returnedClass() {
return java.util.Date.class;
}
public boolean equals(Object x, Object y) throws HibernateException {
if (x instanceof Date) {
Date date1 = (Date) x;
if (y instanceof Date) {
Date date2 = (Date) y;
//if(shortDate.format(date1).equalsIgnoreCase(shortDate.format(date2))){
if(date1.equals(date2)){
return true;
}
}
}
return false;
}
public Object nullSafeGet(ResultSet rs, String[] names, Object owner)throws HibernateException, SQLException
{
Date date;
long milliseconds;
Timestamp timestamp = (Timestamp) Hibernate.TIMESTAMP.nullSafeGet(rs, names[0]);//I think so :(
if( timestamp==null )
{
return null;
}
else
{
milliseconds = timestamp.getTime() + (timestamp.getNanos() / 1000000);
try {
log.info(" The date coming back "+shortDate.parse(shortDate.format(milliseconds)));
return shortDate.parse(shortDate.format(milliseconds));
}
catch(ParseException pe){
throw new RuntimeException(pe.getMessage());
}
}
}
public void nullSafeSet(PreparedStatement st, Object value, int index)throws HibernateException, SQLException
{
// handle the NULL
if( value==null )
{
st.setTimestamp(index, null);
return;
}
if( ! Date.class.isAssignableFrom(value.getClass()) ) {
throw new IllegalArgumentException("Required a (java.util.Date) but received a [" + value.getClass() + "]");
}
Timestamp tstamp = null;
if( (value instanceof Timestamp) )
{
tstamp = (Timestamp) value;
}
else
{
tstamp = new Timestamp( ((Date) value).getTime() );
}
st.setTimestamp(index, tstamp);
}
public Object deepCopy(Object value) throws HibernateException {
if( value==null )
{
return null;
}
else
{
return ((Date) value).clone();
}
}
public boolean isMutable() {
return true;
}
//optional
public Serializable disassemble(Object value) throws HibernateException {
return (Serializable) value;
}
public Object assemble(Serializable cached, Object owner) throws HibernateException {
return cached;
}
public Object replace(Object original, Object target, Object owner) throws HibernateException {
return deepCopy(original);
}
public int hashCode(Object x){
return x.hashCode();
}
}
my criteria factory
Code:
public class CriterionFactoryForFilterTypes {
private final static ArrayList<Criterion> criterion;
private final static SimpleDateFormat format;
private final static Logger log;
static{
criterion = new ArrayList<Criterion>();
format = new SimpleDateFormat("yyyy-MM-dd");
log = Logger.getLogger(CriterionFactoryForFilterTypes.class);
}
public static List<Criterion> matchTypeToCriteria(final List<Filter> filters){
if(!criterion.isEmpty())
criterion.clear();
for(Filter f:filters)
getCriteria(f);
return Collections.unmodifiableList(criterion);
}
private static void getCriteria(final Filter filter){
Date date;
final String type = filter.getType();
if(type.equals("string"))
criterion.add(Restrictions.ilike(filter.getField(),filter.getValue(),MatchMode.ANYWHERE));
if(type.equals("numeric"))
{
switch(filter.getComparison())
{
case eq:criterion.add(Restrictions.eq(filter.getField(), new Long(filter.getValue())));break;
case lt:criterion.add(Restrictions.lt(filter.getField(), new Long(filter.getValue())));break;
case gt:criterion.add(Restrictions.gt(filter.getField(), new Long(filter.getValue())));break;
}
}
if(type.equals("date"))
{
try
{
date = format.parse(filter.getValue().trim());
}
catch(ParseException pe)
{
throw new RuntimeException("The date was not formatted correctly [ format: " + format.toPattern()+" value = "+filter.getValue().trim() + "]");
}
switch(filter.getComparison())
{
case eq:criterion.add(Restrictions.eq(filter.getField(), date));log.info("From the criterion factory "+ date.getTime()+ " and pattern "+format.toPattern());break;
case lt:criterion.add(Restrictions.lt(filter.getField(), date));break;
case gt:criterion.add(Restrictions.gt(filter.getField(), date));break;
}
}
if(type.equals("list"))
{
String[] inParameters = filter.getValue().split(",");
criterion.add(Restrictions.in(filter.getField(),inParameters));
}
}
}
Any ideas anyone???!