Пользовательские кодеки читают проблему в Spring data cassandra

У меня есть поле временной метки в моей таблице Cassandra, которое я хочу сопоставить с Java Мгновенный. Это довольно легко сделать во время письма.

Я добавляю пользовательские кодеки.

@Override
protected ClusterBuilderConfigurer getClusterBuilderConfigurer() {
    return clusterBuilder -> {

        clusterBuilder.getConfiguration().getCodecRegistry()
                      .register(InstantCodec.instance,
                                LocalDateCodec.instance,
                                LocalTimeCodec.instance);
        return clusterBuilder;
    };
}

Скажите Spring не преобразовывать мой Instant в какой-то другой тип.

private enum InstantWriteConverter implements Converter<Instant, Instant> {
    INSTANT;

    @Override
    public Instant convert(Instant source) {
        return source;
    }
}

Таким образом, Instant передается как есть и обрабатывается InstantCodec.

Но при чтении из Кассандры метка времени чтения сопоставляется с Дата, и я не могу изменить это поведение. Из-за этого мне нужно добавить в свою сущность специальный конструктор, чтобы преобразовать дату в мгновенную.

Мой анализ. При анализе данных строки Cassandra выполняет поиск, чтобы найти подходящий кодек. Он не учитывает типы параметров предоставленного конструктора сущности и просто выбирает первый кодек, который может обрабатывать данные строки. В моем случае он выбирает кодек timestamp-> date, потому что он присутствует перед кодеком timestamp-> мгновенного в список кодеков CodecRegistry.

Есть ли способ напрямую преобразовать метку времени в Instant?

РЕДАКТИРОВАТЬ

пытался зарегистрировать преобразователи чтения и записи, но преобразователь чтения не привыкает.

    @WritingConverter
private enum InstantWriteConverter implements Converter<Instant, Long> {
    INSTANT;

    @Override
    public Long convert(Instant source) {
        return source.toEpochMilli();
    }
}

@ReadingConverter
private enum InstantReadConverter implements Converter<Long, Instant> {
    INSTANT;

    @Override
    public Instant convert(Long source) {
        return Instant.ofEpochMilli(source);
    }
}

person Dexter    schedule 15.02.2017    source источник
comment
Вы можете зарегистрировать настраиваемый кортеж преобразователя (преобразователи чтения и записи) для чтения Instant (см. docs.spring.io/spring-data/cassandra/docs/current/reference/)   -  person mp911de    schedule 15.02.2017
comment
Во время операции чтения конвертеры не привыкают, Instant все равно конвертируется в java.util.Date.   -  person Dexter    schedule 20.02.2017


Ответы (1)


Все заработало. Конвертер чтения должен находиться на уровне Row-> Class.

    @Override
    protected ClusterBuilderConfigurer getClusterBuilderConfigurer() {
        return clusterBuilder -> {

            clusterBuilder.getConfiguration().getCodecRegistry()
                          .register(InstantCodec.instance,
                                    LocalDateCodec.instance,
                                    LocalTimeCodec.instance);
            return clusterBuilder;
        };
    }

    @Override
    public CustomConversions customConversions() {
        return new CustomConversions(
                Arrays.asList(ReadConverter.INSTANCE,
                              InstantWriteConverter.INSTANCE,
                              LocalTimeWriteConverter.INSTANCE,
                              DurationWriteConverter.INSTANCE,
                              LocalDateWriteConverter.INSTANCE));
    }

@ReadingConverter
private enum ReadConverter implements Converter<Row, FlightFareInfo> {
    INSTANCE;

    @Override
    public FlightFareInfo convert(Row source) {

        return FlightFareInfo.convertFromRow(source);
    }
}
person Dexter    schedule 20.02.2017