Spring Data y MongoDB: Relaciones ManyToOne en varias colecciones

Índice

Introducción

En mi último artículo, vimos un ejemplo de como construir una aplicación Web con String MVC usando como persistencia Spring Data sobre MongoDB además de como realizar tests de integración usando un servidor MongoDB embebido.

En este tutorial pretendo dar un paso más a mi en mis investigaciones respecto al tema de MongoDB, modificando el proyecto de mi anterior artículo para que los objetos de negocio se almacenen en su propia colección, evitándose así la duplicidad de la información con los problemas que esto conlleva.

Para continuar, es importante saber que información se trata y como se relaciona:

  • Tenemos usuarios que crean notas y una nota tiene N enlaces.
  • Un usuario (User) se compone de un id, un email y un nombre.
  • Una nota (Note) se compone de un título, un contenido y una fecha de creación)
  • Una enlace (Link) se compone de un id y un enlace.

En mi anterior solución usé documentos embebidos, almacenando la información de la siguiente forma:

db.note.insert({_id : "1", title : "Titulo 1", content: "Contenido 1", created: new Date(61324466400000),
                owner: {_id: 1, email: "cgpcosmad@gmail.com", name: "Carlos García"},
                links: [{_id: 1, url: "http://carlos-garcia.es"}, {_id: 2, url: "http://mobiletest.es"}]});

Ahora pretendo que la información se almacene de la siguiente forma, tres colecciones y referencias por su id:

db.user.insert({_id: "1", email: "cgpcosmad@gmail.com",      name: "Carlos García"});
db.link.insert([{_id: "1", url: "http://carlos-garcia.es"}, {_id: "2", url: "http://mobiletest.es"}]);
db.note.insert({_id : "1", title : "Titulo 1", content: "Contenido 1", created: new Date(61324466400000),
               user: {_id: "1"}, links: [{_id: "1"}, {_id: "2"}]});

Ejemplo

Esta aplicación se compone de bastantes archivos, así que para no extenderme sólo veremos los archivos más importantes El lector podrá descargarse el proyecto y analizar todo más detenidamente.

Configuración especifica de Spring para MongoDB

/src/main/resources/core_mongodb.xml

Este archivo será importado por la configuración principal de la aplicación.

El Driver de MongoDB trabaja con DBObject que es capaz de traducir a objetos de negocio siempre y cuando los nombres de los atributos y los atributos de objeto de negocio coincidan con el documento de Mongo.

Como en el documento Note guardamos los IDS del usuario que la creó y los enlaces, necesitamos realizar un trabajo extra para extraer además de su colección el usuario y los enlaces, para esto usaremos los Converter.

Lamentablemente, en la configuración necesaria hay una dependencia circular entre el Template y el Converter, por lo que para evitarla voy a obtener las dependencias necesarias del Converter en tiempo de ejecución cuando ya se haya inicializado todo el contexto de Spring.

/src/main/java/es/carlosgarcia/converter/NoteConverterReader.java

/src/main/java/es/carlosgarcia/converter/NoteConverterWritter.java

El repositorio para trabajo con notas

/src/main/java/es/carlosgarcia/repository/NoteRepository.java

El test del repositorio de trabajo con notas.

/src/test/java/es/carlosgarcia/repository/NoteRepositoryTest.java

Configuración de Spring para los tests:

/src/test/resources/app-test.xml

Descargar código fuente

Puedes descargarte el proyecto.

Referencias:

Conclusiones:

Aunque en este tutorial he dado un importante paso más en mis investigaciones del uso de MongoDB en aplicaciones empresariales, aún queda por aprender y refinar.

Si nos fijamos bien, esta solución que hemos desarrollado siempre que se carga una nota se cargan sus dependencias (EAGER), por lo que en muchas soluciones esto es un problema.

Creo que es imprescindible saber como conseguir que sólo se cargen los enlaces cuando se necesiten y no antes (LAZY), de momento con SpringData fecha de hoy (2013) veo que no es posible, por lo que seguiremos investigando en como conseguirlo usando el soporte para JPA y Morphia (que no se si es posible o no).

Un saludo. Carlos García. @cgpcosmad

Categorías del artículo

Comentarios de los lectores