Hibernate自定义UserType无法正常工作

我已经创建了一个UserType(见下文)来处理我们的mySQL数据库中的情况,我们一直在保存null date作为0000-00-00 00:00:00。

当我尝试使用null为dispDT持久保存我的实体时(见下文),它会生成此exception:“javax.persistence.PersistenceException:org.hibernate.PropertyValueException:not-null属性引用null或transient值:myEntity.dispDt”

通过在MySQLTimeStampUserType中的每个方法中设置断点,我可以看到它调用deepCopy方法并且从不调用nullSafeSet方法。 我认为nuyllSafeSet方法的重点是允许我在持久化之前操纵该值。 我究竟做错了什么?

实体注释

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

用户类型类

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

您的问题不在于您的UserType – 这是因为您已将您的属性声明为非null(使用@Basic optional =“false”),但您将其设置为null。

也就是说,我要小心在deepCopy /汇编/反汇编方法中返回原始值。 java.util.Date 可变的,你可能会在那里遇到麻烦。

这些细微差别在这里得到了很好的讨论: http : //blog.xebia.com/2009/11/09/understanding-and-writing-hibernate-user-types/

DATE和TIME的准备工作解决方案: 如何使用Hibernate映射MySQL DATE’EMA’&TIME ’00:00:00′

感谢Preston的代码和ChssPly76的有用评论。