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.