Hibernate自定义UserType不起作用

Hibernate自定义UserType不起作用

本文介绍了Hibernate自定义UserType不起作用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我创建了一个UserType(见下文)来处理我们的mySQL数据库中的情况,我们已经将空日期保存为0000-00-00 00:00:00。



当我尝试用dispDT的null(参见下文)持久化实体时,它会生成此异常:javax.persistence.PersistenceException:org.hibernate.PropertyValueException:not-null属性引用null或瞬态值:myEntity.dispDt通过在MySQLTimeStampUserType中的每个方法中设置一个断点,我可以看到它调用了deepCopy方法,并且从不调用nullSafeSet方法。我认为nuyllSafeSet方法的全部重点是让我在继续使用之前操纵这个值。我做错了什么?



实体注解

  @Basic可选= false)
@Column(name =disp_dt)
@Type(type =mypackage.MySQLTimeStampUserType)
// @Temporal(TemporalType.TIMESTAMP)
private日期显示;

用户类型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;

$ b $ 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);



$ b public int hashCode(Object arg0)throws HibernateException {
throw new UnsupportedOperationException(Not supported yet。);
}
$ b $ public Object nullSafeGet(ResultSet resultSet,String [] names,Object owner)throws HibernateException,SQLException {
//如果日期为0000-00-00 00: 00:00返回null,否则返回时间戳
日期结果= null;如果(!resultSet.wasNull()){
if(!resultSet.getString(names [0])。equals(0000-00-00 00:00:00)){
result = resultSet.getDate(names [0]);
}
}
返回结果;

$ b $ public void nullSafeSet(PreparedStatement statement,Object value,int index)throws HibernateException,SQLException {
//如果日期为null,则将值设置为0000-00 -00 00:00:00否则保存时间戳
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;

$ b $ public 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 Object(Object original,Object target,Object owner)throws HibernateException {
return original;


$ / code $ / pre

解决方案

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



说,我会小心在deepCopy /汇编/反汇编方法中返回原始值。 java.util.Date 是可变的,您可能会在那里寻求麻烦。


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;
}
}
解决方案

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.

这篇关于Hibernate自定义UserType不起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-24 15:08