Hibernate custom UserType isn't working

hibernate, java, usertype

Solution

Your problem is not with your UserType - it's with the fact that you've declared your property as not-null (using @Basic optional="false") and yet you're setting it to null.

That said, I'd be careful about returning the original value in deepCopy / assemble / disassemble methods. java.util.Date is mutable and you may be asking for trouble there.

Problem

I've created a UserType (see below) to handle a situation in our mySQL database where we've been saving null dates as 0000-00-00 00:00:00. When I try and persist my entity with a null for dispDT (see below) it generates this exception: "javax.persistence.PersistenceException: org.hibernate.PropertyValueException: not-null property references a null or transient value: myEntity.dispDt" By setting a breakpoint in every method in MySQLTimeStampUserType I can see it calls the deepCopy method and never calls the nullSafeSet method. I thought the whole point of the nuyllSafeSet method was to allow me to manipulate the value before persisting it. What am I doing wrong? Entity Annotations ``` @Basic(optional = false) @Column(name = "disp_dt") @Type(type = "mypackage.MySQLTimeStampUserType") // @Temporal(TemporalType.TIMESTAMP) private Date dispDt; ``` User Type class ``` 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; } } ```

Original source