2009-10-14 13 views
6

Ich habe ein Usertype erstellt (siehe unten) eine Situation, in unserer mySQL-Datenbank zu behandeln, in denen wir null Daten wie 0000-00-00 00.00.00 Speicher haben.Hibernate individuelle Usertype funktioniert nicht

Wenn ich versuche, meine Entity mit einem NULL für dispDT (siehe unten) zu erhalten, generiert es die folgende Ausnahme: "javax.persistence.PersistenceException: org.hibernate.PropertyValueException: not-null-Eigenschaft verweist auf einen Null- oder Transientenwert: myEntity .dispDt "

Durch Festlegen eines Haltepunkts in jeder Methode in MySQLTimeStampUserType kann ich sehen, dass es die deepCopy-Methode aufruft und niemals die nullSafeSet-Methode aufruft. Ich dachte, der ganze Sinn der Methode nuyllSafeSet bestünde darin, den Wert zu manipulieren, bevor ich ihn behalte. Was mache ich falsch?

Entity Anmerkungen

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

Benutzertyp Klasse

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

Antwort

4

Ihr Problem ist nicht mit Ihrem Usertype - es mit der Tatsache, dass Sie Ihre Immobilie als nicht-null deklariert haben (mit @Basic optional = "false") und trotzdem setzen Sie es auf null.

Das heißt, ich vorsichtig sein würde über den ursprünglichen Wert in deepcopy/Ein-/Ausbau Methoden zurück. java.util.Date ist wandelbar und Sie können dort für Ärger fragen.

+0

Die Datenbank erlaubt es nicht, einen Nullwert für diese Spalte. Stattdessen haben sie es mit "0000-00-00 00:00:00" gefüllt. Ich dachte, der Zweck des UserType war es, mir zu ermöglichen, den Nullwert in "0000-00-00 00:00:00" zu konvertieren. – Preston

+2

Ich spreche nicht über die Datenbank. Sie legen diese Eigenschaft in Ihrer Anwendung auf NULL fest. Der Hibernate-Effekt blockiert das, weil er als optional = false abgebildet ist. Entfernen Sie diese Deklaration, und Sie können loslegen - die Datenbank wird in dieser Spalte nicht NULL erhalten, weil Ihr Benutzertyp sie durch Nullen ersetzt. – ChssPly76

Verwandte Themen