Hibernate里自定义UserType时取不到值的问题

前两天我微博提到有个BUG出现了两个月却还没有头绪。这个BUG是这样的:在Hibernate中自定义UserType,从数据库中取值的时候,有时候这个UserType能取到值,但有时候即使数据库有值,取到的也是null。后来负责前端的同事偶然发现,当数据库中某些字段为null的时候,这个UserType就取不到值,如果把这些字段填上内容,就可以取到了。于是这个问题就莫名其妙地解决了。后来经过分析和测试,发现只要UserType的前一个字段为null,这个UserType就肯定取不到值。UserType的代码是这样的:

public class GenderUserType extends StringUserType {

    public Class returnedClass() {
        return Gender.class;
    }
    
    public Object nullSafeGet(ResultSet rs, String[] names, Object owner)
            throws HibernateException, SQLException {
        if (rs.wasNull())    return null;
        String gender = rs.getString(names[0]);
        return Gender.valueOf(gender);
    }

    public void nullSafeSet(PreparedStatement st, Object value, int index)
            throws HibernateException, SQLException {
        if (value == null) {
            st.setNull(index, SQL_TYPE);
        }
        else {
            String gender = ((Gender)value).toString();
            st.setString(index, gender);
        }
    }
}

您能看出问题在哪了吗?对了,就是nullSafeGet里的if (rs.wasNull()) return null;这句。查看wasNull的文档不难发现,这个方法用于判断上次从rs中取出的值是否为null。因此,如果这个UserType的前一个字段为null,这条语句就会返回null。当时我不知道从哪copy了这份代码,于是产生了这样一个表现十分诡异的BUG。

要修复这个BUG是很简单的,只需要调换nullSafeGet里前两行代码即可。

如果UserType是除主键外的第一个字段,在取值的时候还会产生“sqlexception 未读取数据”的异常。

http://topic.csdn.net/u/20110713/22/5b9384fa-91ff-4086-a83c-90c89b355e19.html

http://ytffhvk.iteye.com/blog/169306

http://rayleeya.iteye.com/blog/365237

posted @ 2012-03-26 16:07 麒麟.NET 阅读(...) 评论(...) 编辑 收藏