Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can Hibernate map NULL to the not-a-number float?

Here is my Hibernate mapping of a particular column:

<property name="maxRating" not-null="false" column="max_rating"/>

In the database (Postgres), the column is max_rating double precision, i.e. it is nullable in the table. The Java class being mapped has a member private float maxRating.

Without changing the table definition or the class, is there a way to get Hibernate to map a NULL value in this column to Float.NaN in the instance?

like image 436
wberry Avatar asked Oct 11 '22 06:10

wberry


1 Answers

You should be able to create a user type:

package my.pkg.type;

public class NullNanFloatType implements UserType {

    public int[] sqlTypes() {
        return new int[]{Types.FLOAT};
    }

    public Class returnedClass() {
        return Float.class;
    }

    public boolean equals(Object x, Object y) throws HibernateException {
        return ( x == y ) || ( x != null && x.equals( y ) );
    }

    public int hashCode(Object x) throws HibernateException {
        return x.hashCode();
    }

    public Object nullSafeGet(ResultSet rs, String[] names, Object owner) throws HibernateException, SQLException {
        float value = rs.getFloat(names[0]);
        if (rs.wasNull()) {
            value = Float.NaN;
        }
        return new Float(value);
    }

    public void nullSafeSet(PreparedStatement ps, Object value, int index) throws HibernateException, SQLException {
        if (value == null || Float.isNaN(((Float)value).floatValue())) {
            ps.setNull(index, Types.FLOAT);
        } else {
            ps.setFloat(index, ((Float)value).floatValue());
        }
    }

    public Object deepCopy(Object value) throws HibernateException {
        //returning value should be OK since floats are immutable
        return value;
    }

    public boolean isMutable() {
        return false;
    }

    public Serializable disassemble(Object value) throws HibernateException {
        return (Serializable) value;
    }

    public Object assemble(Serializable cached, Object owner) throws HibernateException {
        return cached;
    }

    public Object replace(Object original, Object target, Object owner) throws HibernateException {
        return original;
    }
}

and then you should be able to set the property mapping to

<property name="maxRating" 
          not-null="false" 
          column="max_rating" 
          type="my.pkg.type.NullNanFloatType" />
like image 199
beny23 Avatar answered Oct 17 '22 22:10

beny23