2009-10-14 12 views
6

Ho creato un UserType (vedi sotto) per gestire una situazione nel nostro database mySQL dove abbiamo salvato le date nulle come 0000-00-00 00:00:00.Hibernate Custom UserType non funziona

Quando provo e persistono mia entità con un nullo per dispDT (vedi sotto) che genera questa eccezione: "javax.persistence.PersistenceException: org.hibernate.PropertyValueException: proprietà non-null fa riferimento a un valore nullo o transitoria: myEntity .dispDt "

Impostando un punto di interruzione in ogni metodo in MySQLTimeStampUserType, è possibile vedere che chiama il metodo deepCopy e non chiama mai il metodo nullSafeSet. Ho pensato che l'intero punto del metodo nuyllSafeSet fosse quello di permettermi di manipolare il valore prima di persisterlo. Che cosa sto facendo di sbagliato?

entità NOTE

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

classe Type utente

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; 
} 
} 

risposta

4

Il tuo problema non è con il vostro UserType - è il fatto che avete dichiarato la vostra proprietà come non-null (utilizzando @Basic optional = "false") eppure lo stai impostando su null.

Detto questo, farei attenzione a restituire il valore originale nei metodi deepCopy/assemblare/disassemblare. java.util.Date è mutabile e potresti essere in difficoltà.

+0

Il database non consente un valore null per questa colonna. Invece lo hanno popolato con "0000-00-00 00:00:00". Pensavo che il punto di UserType fosse di permettermi di convertire il null in "0000-00-00 00:00:00". – Preston

+2

Non sto parlando del database. Stai impostando la proprietà su NULL nella tua applicazione; Hibernate blocca ciò perché è mappato come facoltativo = falso. Rimuovi quella dichiarazione e sarai a posto - il database non otterrà NULL in quella colonna perché il tuo tipo di utente lo sostituirà con zero. – ChssPly76

Problemi correlati