aaberg / sql2o

sql2o is a small library, which makes it easy to convert the result of your sql-statements into objects. No resultset hacking required. Kind of like an orm, but without the sql-generation capabilities. Supports named parameters.
http://sql2o.org
MIT License
1.15k stars 229 forks source link

Converters cannot be registered as service #205

Open CyborTronik opened 9 years ago

CyborTronik commented 9 years ago

I'm getting:

java.util.ServiceConfigurationError: org.sql2o.converters.ConvertersProvider: Provider com.github.cybortronik.registry.repository.sql2o.converters.OffsetDateTimeConverter not a subtype
    at java.util.ServiceLoader.fail(ServiceLoader.java:239)
    at java.util.ServiceLoader.access$300(ServiceLoader.java:185)
    at java.util.ServiceLoader$LazyIterator.nextService(ServiceLoader.java:376)
    at java.util.ServiceLoader$LazyIterator.next(ServiceLoader.java:404)
    at java.util.ServiceLoader$1.next(ServiceLoader.java:480)
    at org.sql2o.converters.Convert.<clinit>(Convert.java:109)
    at org.sql2o.quirks.NoQuirks.converterOf(NoQuirks.java:42)
    at org.sql2o.DefaultResultSetHandlerFactory.newResultSetHandler0(DefaultResultSetHandlerFactory.java:144)
    at org.sql2o.DefaultResultSetHandlerFactory.access$200(DefaultResultSetHandlerFactory.java:16)
    at org.sql2o.DefaultResultSetHandlerFactory$3.evaluate(DefaultResultSetHandlerFactory.java:118)
    at org.sql2o.DefaultResultSetHandlerFactory$3.evaluate(DefaultResultSetHandlerFactory.java:114)
    at org.sql2o.tools.AbstractCache.get(AbstractCache.java:49)
    at org.sql2o.DefaultResultSetHandlerFactory.newResultSetHandler(DefaultResultSetHan

for class registered in META-INF/services/org.sql2o.converters.ConvertersProvider :

package com.github.cybortronik.registry.repository.sql2o.converters;

import org.sql2o.converters.Converter;
import org.sql2o.converters.ConverterException;

import java.sql.Timestamp;
import java.time.*;

/**
 * Created by stanislav on 11/20/15.
 */
public class OffsetDateTimeConverter implements Converter<OffsetDateTime> {

    @Override
    public OffsetDateTime convert(Object val) throws ConverterException {
        Timestamp timestamp = (Timestamp) val;
        if (val == null)
            return null;

        Instant instant = timestamp.toInstant();
        return OffsetDateTime.ofInstant(instant, ZoneId.systemDefault());
    }

    @Override
    public Object toDatabaseParam(OffsetDateTime val) {
        if (val == null)
            return null;
        return Timestamp.from(val.toInstant());
    }
}
doganov commented 8 years ago

Generally, the class you should register in META-INF/services/org.sql2o.converters.ConvertersProvider is not the converter per se, but another class which implements org.sql2o.converters.ConvertersProvider. Something like this:

package com.github.cybortronik.registry.repository.sql2o.converters;

import org.sql2o.converters.Converter;
import org.sql2o.converters.ConvertersProvider;

import java.time.OffsetDateTime;
import java.util.Map;

public class Sql2oConvertersProvider implements ConvertersProvider {

    @Override
    public void fill(Map<Class<?>, Converter<?>> mapToFill) {
        mapToFill.put(OffsetDateTime.class, new OffsetDateTimeConverter());
    }
}

Of course, if you want to register only one converter, you could make OffsetDateTimeConverter also implement the ConvertersProvider interface. Then use it as a provider of itself:

    @Override
    public void fill(Map<Class<?>, Converter<?>> mapToFill) {
        mapToFill.put(OffsetDateTime.class, this);
    }