ORMLite and custom data persiter of Optional<Double>

198 views Asked by At

Anyone know how to write custom data persister for Guava's Optional<Double>?
So it could be possible to directly use in entity the code:

@DatabaseField(columnName = "myField")
Optional<Double> myField;

After initial attemps I found a few tricky points. Eg: registering Optional<Double> in mapper - seems that types dictionary flattens it to just Optional.

1

There are 1 answers

0
Grzegorz Dev On

Here is my implementation which ONLY persit to / read from DB.
And DOESN'T handle: arguments in statements, global type registering.

Before use it's worth to read why not to use Optional as object's fied.

Use case:

@DatabaseField(columnName = "myField", persisterClass = OptionalDoubleType.class)
Optional<Double> myField;

Persister:

public class OptionalDoubleType extends BaseDataType {

    private static final OptionalDoubleType singleton = new OptionalDoubleType();

    public static OptionalDoubleType getSingleton() {
        return singleton;
    }

    private OptionalDoubleType() {
        super(SqlType.DOUBLE, null);
    }

    protected OptionalDoubleType(SqlType sqlType, Class<?>[] classes) {
        super(sqlType, classes);
    }


    @Override
    public Object resultToJava(FieldType fieldType, DatabaseResults results, int columnPos) throws SQLException {
        double aDouble = results.getDouble(columnPos);
        if (results.wasNull(columnPos))
            return Optional.absent();
        else
            return Optional.of(aDouble);
    }

    @Override
    public Object javaToSqlArg(FieldType fieldType, Object javaObject) throws SQLException {
        Optional<Double> optDbl = (Optional<Double>) javaObject;
        if (optDbl.isPresent())
            return optDbl.get();
        else
            return null;
    }

    @Override
    public Object parseDefaultString(FieldType fieldType, String defaultStr) throws SQLException {
        throw new UnsupportedOperationException();
    }

    @Override
    public Object resultToSqlArg(FieldType fieldType, DatabaseResults results, int columnPos) throws SQLException {
        throw new UnsupportedOperationException();
    }

    // BUGFIX: there is a bug in ORMLite which causes that
    // decoding 'sql null' to Optional.absent() is wrong when 
    // Entity with Optional<Double> is read as "child entity".
    // It fixes the bug [ugly but works ;]
    @Override
    public boolean isStreamType() {
        return true;
    }


}