ZonedDateTime com Spring Data MongoDB

ZonedDateTime com Spring Data MongoDB

1. Visão geral

O móduloSpring Data MongoDB melhora a legibilidade e usabilidade ao interagir com um banco de dados MongoDB em projetos Spring.

Neste tutorial, vamos nos concentrar em como lidar com os objetos JavaZonedDateTime ao ler e gravar em um banco de dados MongoDB.

2. Configuração

Para trabalhar com o módulo Spring Data MongoDB, precisamos adicionar a seguinte dependência:


    org.springframework.data
    spring-data-mongodb
    2.1.2.RELEASE

A versão mais recente da biblioteca pode ser encontradahere.

Vamos definir uma classe de modelo chamadaAction (com um atributoZonedDateTime):

@Document
public class Action {
    @Id
    private String id;

    private String description;
    private ZonedDateTime time;

    // constructor, getters and setters
}

Para interagir com o MongoDB, também criaremos uma interface que estende oMongoRepository:

public interface ActionRepository extends MongoRepository { }

Agora vamos definir um teste que irá inserir um objetoAction em um MongoDB e afirmar que ele foi armazenado com o tempo correto. Na avaliação de assert, estamos removendo as informações de nanossegundos, pois o tipoDate do MongoDB tem uma precisão de milissegundos:

@Test
public void givenSavedAction_TimeIsRetrievedCorrectly() {
    String id = "testId";
    ZonedDateTime now = ZonedDateTime.now(ZoneOffset.UTC);

    actionRepository.save(new Action(id, "click-action", now));
    Action savedAction = actionRepository.findById(id).get();

    Assert.assertEquals(now.withNano(0), savedAction.getTime().withNano(0));
}

Fora da caixa, obteremos o seguinte erro ao executar nosso teste:

org.bson.codecs.configuration.CodecConfigurationException:
  Can't find a codec for class java.time.ZonedDateTime

Spring Data MongoDB has no ZonedDateTime converters defined. Vamos ver como podemos configurá-los.

3. Conversores MongoDB

Podemos lidar com objetosZonedDateTime (em todos os modelos) definindo um conversor para leitura de um MongoDB e outro para escrita nele.

Para leitura, estamos convertendo de um objetoDate em um objetoZonedDateTime. No próximo exemplo, usamosZoneOffset.UTC uma vez que o objetoDate não armazena informações de zona:

public class ZonedDateTimeReadConverter implements Converter {
    @Override
    public ZonedDateTime convert(Date date) {
        return date.toInstant().atZone(ZoneOffset.UTC);
    }
}

Então, estamos convertendo de um objetoZonedDateTime em um objetoDate. Podemos adicionar as informações da zona a outro campo, se necessário:

public class ZonedDateTimeWriteConverter implements Converter {
    @Override
    public Date convert(ZonedDateTime zonedDateTime) {
        return Date.from(zonedDateTime.toInstant());
    }
}

Como os objetosDate não armazenam um deslocamento de zona, usamosUTC em nossos exemplos. Com a areiaZonedDateTimeReadConverter e oZonedDateTimeWriteConverter adicionado aoMongoCustomConversions, nosso teste passará agora.

Uma impressão simples do objeto armazenado terá a seguinte aparência:

Action{id='testId', description='click', time=2018-11-08T08:03:11.257Z}

Para aprender mais sobre como registrar conversores MongoDB, podemos consultarthis tutorial.

4. Conclusões

Neste artigo rápido, vimos como criar conversores MongoDB para lidar com objetos JavaZonedDateTime.

A implementação de todos esses snippets pode ser encontradaover on GitHub.