Hibernate custom user type not working

I created a UserType (see below) to handle the situation in our mySQL database, where we store zero dates as 0000-00-00 00:00:00.

When I try and save my object with a null value for dispDT (see below), it throws this exception: "javax.persistence.PersistenceException: org.hibernate.PropertyValueException: the not-null property refers to a null value or a transition: myEntity. DispDtt "

By setting a breakpoint in each method in MySQLTimeStampUserType, I see that it calls the deepCopy method and never calls the nullSafeSet method. I thought the whole point of the nuyllSafeSet method is to allow me to manipulate the value before storing 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; 

Custom class type

 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; } } 
+6
java hibernate usertype
source share
3 answers

Your problem is not related to your UserType - it is the fact that you declared your property as not-null (using @Basic optional = "false"), but you set it to null.

However, I would be careful in returning the original value in the deepCopy / assembly / disassemble methods. java.util.Date is volatile and you can ask for problems about it.

+4
source share
+4
source share

Ready-made and working solution for DATE and TIME: How to match MySQL DATE '0000-00-00' and TIME '00: 00: 00 'with Hibernate

Thanks to Preston for the code and ChssPly76 for helpful comments.

0
source share

All Articles