0

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.

Grzegorz Dev
  • 3,073
  • 1
  • 18
  • 22
  • 1
    Note that there are [good reasons to avoid Optional fields](http://stackoverflow.com/a/24564612/581205). So even the JDK8 authors think that `Optional` is a bad idea in this case (the Guava's authors may differ as they've made it `Serializable`) and I fully agree with [this rant](https://groups.google.com/d/msg/project-lombok/ROx9rGRb6lI/EF0lk8F0N10J). – maaartinus Jun 07 '15 at 16:27

1 Answers1

0

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


}
Community
  • 1
  • 1
Grzegorz Dev
  • 3,073
  • 1
  • 18
  • 22