Translate

jueves, 26 de julio de 2012

Problemas típicos de configuración de los Repositories de JPA y Mongodb combinados

Typical problems configuring JPA and Mongodb Repositories together

Utilizando Spring Data tenemos la posibilidad de acceder fácilmente a datos almacenados en base de datos relacionales como Mysql, Postgres, etc.. a través de Spring data JPA y también a base de datos NoSQL como por ejemplo MongoDB con Spring Data MongoDB.

Una de las principales carácterísticas de Spring Data es que ya no es necesaria la generación de classes DAO con las opreciones básicas como save, delete, update y find ya que ya vienen implementadas por defecto.

Para que eso funcione creamos una interfaz que heredará de una clase de Spring Data y ya tendrá todas las operaciones disponibles.


JPA (AnnouncementDao.java)
-
package com.antuansoft.daos.jpa
import org.springframework.data.jpa.repository.JpaRepository;

import com.antuansoft.Announcement;

public interface AnnouncementDao extends JpaRepository<Announcement, String>, CustomAnnouncementDao{


}


--

MongoDB (CompanuDao.java)


-
package com.antuansoft.daos.mongodb
import java.util.List;

import org.springframework.data.mongodb.repository.MongoRepository;
import org.springframework.data.querydsl.QueryDslPredicateExecutor;

import com.antuansoft.pojo.Company;

public interface CompanyDao extends MongoRepository<Company, String>, QueryDslPredicateExecutor<Company>{

}
--

Para que estos daos funcionen correctamente en nuestro contexto de Spring tenemos que  configurarlo en los xml a través de unos repositories que mapeen estas interfaces indicándole en la opción base-package que páquete(o alguno de sus hijos) contienen los DAOS.


Ambas opciones podemos combinarlas en nuestra arquitectura de datos pero lo normal cuando integramos las dos maneras de acceso dentro de un mismo proyecto es que nos den los siguientes errores:

1º Error típico:

-
Caused by: java.lang.IllegalArgumentException: Not an managed type: class com.antuansoft.pojos.Company
 at org.hibernate.ejb.metamodel.MetamodelImpl.managedType(MetamodelImpl.java:171)
 at org.springframework.data.jpa.repository.support.JpaMetamodelEntityInformation.<init>(JpaMetamodelEntityInformation.java:58)
 at org.springframework.data.jpa.repository.support.JpaEntityInformationSupport.getMetadata(JpaEntityInformationSupport.java:65)
 at org.springframework.data.jpa.repository.support.JpaRepositoryFactory.getEntityInformation(JpaRepositoryFactory.java:149)
 at org.springframework.data.jpa.repository.support.JpaRepositoryFactory.getTargetRepository(JpaRepositoryFactory.java:87)
 at org.springframework.data.jpa.repository.support.JpaRepositoryFactory.getTargetRepository(JpaRepositoryFactory.java:70)
 at org.springframework.data.repository.core.support.RepositoryFactorySupport.getRepository(RepositoryFactorySupport.java:137)
 at org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.getObject(RepositoryFactoryBeanSupport.java:125)
 at org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.getObject(RepositoryFactoryBeanSupport.java:41)
 at org.springframework.beans.factory.support.FactoryBeanRegistrySupport.doGetObjectFromFactoryBean(FactoryBeanRegistrySupport.java:142)
 ... 63 more

--


Este error ocurre por que JPA ha mapeado un DAO de Mongodb, esto ocurre cuando el base-package de ambas configuraciones es el mismo o el de mongo está dentro del de JPA. Por lo tanto JPA intentará configurar un DAO de Mongodb y no podrá procesar la Clase Company que es de Mongobd.

La configuración correcta sería que los paquetes donde están los daos sean distintos y no estén anidados.


JPA
-
<jpa:repositories base-package="com.antuansoft.daos.jpa"></jpa:repositories>
--


Mongodb
-
<mongo:repositories base-package="com.antuansoft.daos.mongodb"/>
--


2º Error típico:

El pojo del interface DAO no está configurados correctamente a través de la etiqueta  @Entity

Los pojos de JPA utilizan la @Entity
-
import javax.persistence.Entity;
--

Los pojos de MongoDB utilizan la @Entity
-
import com.google.code.morphia.annotations.Entity;
--

Si configuramos un pojo de MongoDb con una entity de JPA nos dará el siguiente error
-
Caused by: org.hibernate.AnnotationException: No identifier specified for entity: com.antuansoft.pojos.Company
 at org.hibernate.cfg.InheritanceState.determineDefaultAccessType(InheritanceState.java:268)
 at org.hibernate.cfg.InheritanceState.getElementsToProcess(InheritanceState.java:223)
 at org.hibernate.cfg.AnnotationBinder.bindClass(AnnotationBinder.java:686)
 at org.hibernate.cfg.Configuration$MetadataSourceQueue.processAnnotatedClassesQueue(Configuration.java:3977)
 at org.hibernate.cfg.Configuration$MetadataSourceQueue.processMetadata(Configuration.java:3931)
 at org.hibernate.cfg.Configuration.secondPassCompile(Configuration.java:1368)
 at org.hibernate.cfg.Configuration.buildMappings(Configuration.java:1345)
 at org.hibernate.ejb.Ejb3Configuration.buildMappings(Ejb3Configuration.java:1477)
 at org.hibernate.ejb.EventListenerConfigurator.configure(EventListenerConfigurator.java:193)
 at org.hibernate.ejb.Ejb3Configuration.configure(Ejb3Configuration.java:1096)
 at org.hibernate.ejb.Ejb3Configuration.configure(Ejb3Configuration.java:685)
 at org.hibernate.ejb.HibernatePersistence.createContainerEntityManagerFactory(HibernatePersistence.java:73)
 at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:268)
 at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:310)
 at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1514)
 at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1452)
--

Para finalizar os dejo unas referencias interesantes para ver como realizar estas configuraciones básicas.

Configuración basica de Spring Data Mongobd (mirad las otras 2 partes tb están bien)
Capa de persistencia con Spring Data JPA

No hay comentarios:

Publicar un comentario