2009-10-14 10 views
6

He creado un UserType (ver a continuación) para manejar una situación en nuestra base de datos mySQL donde hemos estado guardando fechas nulas como 0000-00-00 00:00:00.Hibernate personalizado UserType no funciona

Cuando intento y persisto mi entidad con un nulo para dispDT (ver más abajo) se genera esta excepción: "javax.persistence.PersistenceException: org.hibernate.PropertyValueException: la propiedad not-null hace referencia a un valor nulo o transitorio: myEntity .dispDt "

Al establecer un punto de interrupción en cada método en MySQLTimeStampUserType puedo ver que llama al método deepCopy y nunca llama al método nullSafeSet. Pensé que el objetivo del método nuyllSafeSet era permitirme manipular el valor antes de persistir. ¿Qué estoy haciendo mal?

Entidad Anotaciones

@Basic(optional = false) 
@Column(name = "disp_dt") 
@Type(type = "mypackage.MySQLTimeStampUserType") 
// @Temporal(TemporalType.TIMESTAMP) 
private Date dispDt; 

clase Tipo de usuario

public class MySQLTimeStampUserType implements UserType { 

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

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

public Class returnedClass() { 
    return Date.class; 
} 

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

} 

public int hashCode(Object arg0) throws HibernateException { 
    throw new UnsupportedOperationException("Not supported yet."); 
} 

public Object nullSafeGet(ResultSet resultSet, String[] names, Object owner) throws HibernateException, SQLException { 
    // if the date is 0000-00-00 00:00:00 return null, else return the timestamp 
    Date result = null; 
    if (!resultSet.wasNull()) { 
     if (!resultSet.getString(names[0]).equals("0000-00-00 00:00:00")) { 
      result = resultSet.getDate(names[0]); 
     } 
    } 
    return result; 
} 

public void nullSafeSet(PreparedStatement statement, Object value, int index) throws HibernateException, SQLException { 
    // if the date is null set the value to "0000-00-00 00:00:00" else save the timestamp 
    if (value == null) { 
     statement.setString(index, "0000-00-00 00:00:00"); 
    } else { 
     statement.setTimestamp(index,(Timestamp) value); 
    } 

} 

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

public boolean isMutable() { 
    return false; 
} 

public Serializable disassemble(Object value) throws HibernateException { 
    throw new UnsupportedOperationException("Not supported yet."); 
} 

public Object assemble(Serializable cached, Object owner) throws HibernateException { 
    throw new UnsupportedOperationException("Not supported yet."); 
} 

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

Respuesta

4

Su problema no es con su tipo de usuario - es el hecho de que se ha declarado en su propiedad como no nulas (usando @Basic opcional = "false") y sin embargo, lo está estableciendo en nulo.

Dicho esto, tendré cuidado de devolver el valor original en los métodos deepCopy/assemble/disassemble. java.util.Date es mutable y es posible que esté buscando problemas allí.

+0

La base de datos no permite un valor nulo para esta columna. En cambio, lo han poblado con "0000-00-00 00:00:00". Pensé que el objetivo del UserType era permitirme convertir el null a "0000-00-00 00:00:00". – Preston

+2

No estoy hablando de la base de datos. Está configurando esa propiedad en NULL en su aplicación; Hibernate se resiste a eso porque está mapeado como opcional = falso. Elimine esa declaración y estará listo: la base de datos no obtendrá NULL en esa columna porque su tipo de usuario la reemplazará con ceros. – ChssPly76

Cuestiones relacionadas