El driver Java de MongoDB es un poco retorcido

logo MongoDB

Estoy jugueteando y publicando una serie de artículos de MongoDB con Java. Y en uno de ellos, me he puesto a mirar cómo utilizar POJOs de Java con MongoDB. La utilización es fácil, o al menos, eso parece con un «Hola Mundo». Pero la cofiguración para que pueda utilizar POJOs es tan fea como la siguiente

PojoCodecProvider pojoCodecProvider = PojoCodecProvider.builder().automatic(true).build();
CodecRegistry pojoCodecRegistry = CodecRegistries.fromRegistries(
   MongoClientSettings.getDefaultCodecRegistry(), CodecRegistries.fromProviders(pojoCodecProvider));

Ni más ni menos que todo eso. Y explicarlo es, si no complejo, al menos largo.

Primero obtener una intancia de un PojoCodecProvider. Eso se hace con el método estático builder(), concatenando algo de configuración automatic(true) para que sea capaz de tratar automáticamente cualquier POJO y finalmente llamando a build(). Nada complicado de momento. Solo explicar que es un CodecProvier en MongoDB y ya de paso, que es un Codec.

Un Codec es una clase que es capaz de convertir una clase nuestra de Java en un documento bson u obtener nuestra clase Java a partir de un documento bson. bson es como json, pero codifcado en binario en vez de texto. Esto hace que no sea legible para un humano, pero sí ocupa menos espacio y es más eficiente para almacenar o transmitir un documento json.

Y un CodecProvider es una clase capaz de crear Codec específicos para clases concretas. En este caso, nuestro PojoCodecProvider será capaz de crear Codec para cualquier clase Java que sea un POJO. Es decir, que tenga un constructor sin parámetros y que tenga atributos con métodos getter y setter

Vale, nada especialmente raro hasta aquí. Ahora toca decirle a MongoDB que utilice este CodecProvider. Para ello, cuando ya tenemos la conexión con MongoDB establecida y queremos obtener una base de datos, le decimos qué CodecRegistry debe usar llamando a withCodecRegistry()

MongoDatabase database = mongoClient.getDatabase("My_Data_Base").withCodecRegistry(pojoCodecRegistry);

Bueno, un nuevo concepto. Tenemos un CodecProvider, pero necesitamos un CodecRegistry. ¿Qué es un CodecRegistry?. Un CodecRegistry es un registro o alamacén de Codec. Ahí guardamos instancias de Codec, todas las que queramos. MongoDB preguntará ahí cuando tenga que convertir una clase Java a un bson o al revés para buscar el Codec adecuado para esa clase concreta.

Pues vaya, hemos creado un CodecProvider pero necesitamos un CodecRegistry. La única diferencia es que el primero crea un Codec nuevo cada vez que se le pide y el segundo sólo te devuelve los que tiene almacenados.

Para obtener un CodecRegistry a partir del CodecProvider, tenemos la siguiente llamada

CodecRegistries.fromProviders(pojoCodecProvider);

Esto devuelve un CodecRegistry a partir del CodecProvider. Una vez hecho esto, parece fácil, sería pasar el CodecRegistry así obtenido a nuestra llamada a withCodecRegistry(). Pero no es tan fácil.

withCodecRegistry() sólo admite un CodecRegistry. Y por defecto, MongoDB tiene ya uno instalado, con otras cosas que no son POJOs y que necesitamos mantener. Este CodecRegistry por defecto se puede obtener con

MongoClientSettings.getDefaultCodecRegistry()

Así que necesitamos construir un CodecRegistry que tenga todos los Codec por defecto más los Codec de POJOs que hemos creado a partir de nuestro PojoCodecProvider

Menos mal que viene en nuestra ayuda CodecRegistries.fromRegistries(). Esta llamada recibe como parámetros varios CodecRegistry y te devuelve un CodecRegistry con todos los Codec de los CodecRegistry que hemos pasado como parámetros

Así que la llamada chorizo

CodecRegistry pojoCodecRegistry = CodecRegistries.fromRegistries(
                MongoClientSettings.getDefaultCodecRegistry(), CodecRegistries.fromProviders(pojoCodecProvider));

nos devuelve el CodecRegistry que queremos, que tiene todos los Codec por defecto de MongoDB más el nuestro de POJOs. Y ese que obtenemos es el que debemos usar en nuestra llamada a withCodecRegistry().

Pues no sé si es complicado o no, retorcido o no, pero sí sé que he echado un rato en entender esa línea críptica rebuscando por la documentación de MongoDB. Y estoy casi seguro que hay formas más fáciles de obtener un registro de Codec con los de defecto más los que queramos sin involucrar de por medio un CodecProvider.

Esta entrada ha sido publicada en MongoDB y etiquetada como , . Guarda el enlace permanente.

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.