Librería de acceso a datos con Spring y JPA

11
32921

Librería de acceso a datos con Spring y JPA

0. Índice de contenidos.

1. Entorno

Este tutorial está escrito usando el siguiente entorno:

  • Hardware: Portátil Mac Book Pro 17″ (2,6 Ghz Intel Core
    i7, 8 GB
    DDR3)
  • Sistema Operativo: Mac OS X Snow Leopard 10.6.4
  • Spring 3.0.4
  • Maven 2.2.1
  • Eclipse 3.6 (Helios) con M2Eclipse y Spring IDE

2. Introducción

Este tutorial lo voy a aprovechar para crear una librería de acceso al esquema de datos que voy a utilizar en el resto de tutoriales que necesiten un acceso a base de datos.

Uno de los problemas más comunes que nos encontramos cuando participamos en proyectos ya comenzados es que todo el código de acceso a datos se repite en todos y cada uno de los proyectos.

En estos casos lo mejor que se puede hacer es crear una librería para cada uno de los esquemas de base de datos que intervengan en el proyecto. Como vamos a ver en este tutorial.

3. Creando el proyecto con Maven

En este tipo de proyectos en los que vamos a utilizar librerías
de
terceros como Spring, se hace especialmente útil la
utililización de
una herramienta de gestión de dependencias como Maven. Teniendo
Maven
ya instalado en nuestra máquina lo único que tenemos que
hacer es abrir
un terminal y situarnos en el directorio donde vayamos a crear el
proyecto:

mvn archetype:create -DgroupId=com.autentia -DartifactId=model-tutoriales

4. Configurando las dependencias del proyecto

Con el fin de que la edición del proyecto sea más
cómoda podemos
importarlo a un IDE como Eclipse. Para hacer esto, contamos con el
plugin M2Eclipse que es la evolución del conocido EclipseIAM.

Para configurar las dependencias editamos el fichero pom.xml del
proyecto, añadiendo las siguientes:

  
    4.0.0  
    com.autentia  
    model-tutoriales  
    1.0-SNAPSHOT  
    model-tutoriales  
    Librería de acceso a datos para la base de datos "tutoriales"  
      
          
              
                maven-compiler-plugin  
                  
                    UTF-8  
                    1.6  
                    1.6  
                  
              
          
      
      
          
            commons-lang  
            commons-lang  
            2.5  
          
          
            javax.persistence  
            persistence-api  
            1.0  
          
          
            org.springframework  
            spring-core  
            3.0.4.RELEASE  
          
          
            org.springframework  
            spring-tx  
            3.0.4.RELEASE  
          
          
            org.springframework  
            spring-orm  
            3.0.4.RELEASE  
          
          
            org.springframework  
            spring-hibernate3  
            2.0.8  
          
          
            org.hibernate  
            hibernate-entitymanager  
            3.3.1.ga  
          
          
            postgresql  
            postgresql  
            9.0-801.jdbc4  
          
          
            concurrent  
            concurrent  
            1.3.3  
          
          
            javax.annotation  
            jsr250-api  
            1.0  
          
          
            org.springframework  
            spring-test  
            3.0.4.RELEASE  
            test  
          
          
            junit  
            junit  
            4.8.2  
            test  
          
          
            org.hsqldb  
            hsqldb  
            1.8.0.10  
            test  
          
      

Estamos definiendo que el proyecto lo vamos a implementar con Spring y la especificación JPA 1.0 con Hibernate. Además en desarrollo vamos a utilizar PostgreSQL, pero para los tests vamos a utilizar una base de datos en memoria como HSQLDB.

5. Configurando Spring

Para configurar Spring vamos a crear el fichero application-context-model-tutoriales.xml dentro de la carpeta src/main/resources de nuestro proyecto, con el siguiente contenido:

  
  
      
  
      
  
      
  
      
          
      
  
      
          
      
  
      
  

En este fichero estamos definiendo que vamos a utilizar anotaciones y especificamos que archivo se va a encargar de definir el acceso a la base de datos a través de JPA.

6. Configurando JPA

Como hemos definido anteriormente tenemos que crear un fichero llamado persistence.xml dentro de la carpeta src/main/resources/META-INF con el siguiente contenido:

  
    
    org.hibernate.ejb.HibernatePersistence  
      
        
        
        
        
        
        
        
        
        
        
      
    

7. Creando un DAO genérico

Con el fin de no repetir los mismos métodos en todas las clases del proyecto, vamos a crear un DAO genérico con los métodos comunes de acceso a datos, que vamos a definir en la siguiente interfaz:

package com.autentia.tutoriales.dao;  
  
import java.io.Serializable;  
import java.util.List;  
  
public interface GenericDAO  {  
  
    List getAll(Class typeClass);  
  
    T findByPK(Class typeClass, PK id);  
  
    void update(T object);  
  
    void remove(T object);  
  
    void insert(T object);  
      
    List getPaginated(Class typeClass, int startPosition, int maxResult);  
      
    List getOrderedPaginated(Class typeClass, int startPosition, int maxResult, String order, int dir);  
  
} 

En este caso vamos a implementar esta interfaz utilizando Spring y JPA con el siguiente código:

package com.autentia.tutoriales.dao.imp.jpa;

import java.io.Serializable;
import java.util.List;

import javax.persistence.PersistenceContext;
import javax.persistence.Query;

import org.springframework.orm.jpa.support.JpaDaoSupport;
import org.springframework.transaction.annotation.Transactional;

import com.autentia.tutoriales.dao.GenericDAO;

@PersistenceContext(unitName = "tutoriales")
public class GenericDAOJPAImpl<T, PK extends Serializable> extends
		JpaDaoSupport implements GenericDAO<T, PK> {

	@Transactional
	public void insert(T t) {
		getJpaTemplate().persist(t);
	}

	@Transactional(readOnly = true)
	public T findByPK(Class<T> typeClass, PK id) {
		return getJpaTemplate().find(typeClass, id);
	}

	@Transactional(readOnly = true)
	@SuppressWarnings("unchecked")
	public List<T> getAll(Class<T> typeClass) {

		final StringBuilder sql = new StringBuilder("select c from ").append(
				typeClass.getSimpleName()).append(" c");
		return (List<T>) getJpaTemplate().find(sql.toString());

	}

	@Transactional
	public void remove(T object) {
		getJpaTemplate().remove(getJpaTemplate().merge(object));
	}

	@Transactional
	public void update(T object) {
		getJpaTemplate().merge(object);
	}

	@SuppressWarnings("unchecked")
	@Transactional(readOnly = true)
	public List<T> getPaginated(Class<T> typeClass, int startPosition,
			int maxResult) {
		final StringBuilder sql = new StringBuilder("select c from ").append(
				typeClass.getSimpleName()).append(" c");
		final Query query = getJpaTemplate().getEntityManagerFactory()
				.createEntityManager().createQuery(sql.toString());
		query.setFirstResult(startPosition);
		query.setMaxResults(maxResult);

		return (List<T>) query.getResultList();
	}

	@SuppressWarnings("unchecked")
	@Transactional(readOnly = true)
	public List<T> getOrderedPaginated(Class<T> typeClass, int startPosition,
			int maxResult, String order, int dir) {
		String direccion = "ASC";
		if (dir == 2) {
			direccion = "DESC";
		}
		final StringBuilder sql = new StringBuilder("select c from ")
				.append(typeClass.getSimpleName()).append(" c order by ")
				.append(order).append(" ").append(direccion);
		final Query query = getJpaTemplate().getEntityManager().createQuery(
				sql.toString());
		query.setFirstResult(startPosition);
		query.setMaxResults(maxResult);

		return (List<T>) query.getResultList();
	}

}

Para esta implementación utilizamos la facilidades de Spring para JPA extendiendo de JPADaoSupport y con la anotación @PersistenceContext.

8. Creando la entidad Persona

Lo principal cuando utilizamos JPA es la definición de las entidades, en este caso lo vamos a hacer con anotaciones de esta forma:

package com.autentia.tutoriales.model;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;

import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.commons.lang.builder.HashCodeBuilder;

@Entity
public class Persona {

	private static final long serialVersionUID = -5763643296733667671L;

	@Id
	@GeneratedValue(strategy = GenerationType.AUTO)
	@Column(name = "ID_PERSONA", unique = true, nullable = false, precision = 10)
	private Long idPersona;

	@Column(length = 256, name = "NOMBRE")
	private String nombre;

	@Column(length = 256, name = "APELLIDOS")
	private String apellidos;

	@Column(length = 256, name = "DIRECCION")
	private String direccion;

	public void setIdPersona(Long idPersona) {
		this.idPersona = idPersona;
	}

	public Long getIdPersona() {
		return idPersona;
	}

	public String getNombre() {
		return nombre;
	}

	public void setNombre(String nombre) {
		this.nombre = nombre;
	}

	public String getApellidos() {
		return apellidos;
	}

	public void setApellidos(String apellidos) {
		this.apellidos = apellidos;
	}

	public String getDireccion() {
		return direccion;
	}

	public void setDireccion(String direccion) {
		this.direccion = direccion;
	}

	public int hashCode() {
		final HashCodeBuilder hcb = new HashCodeBuilder();
		hcb.append(nombre);
		hcb.append(apellidos);
		hcb.append(direccion);

		return hcb.toHashCode();
	}

	public boolean equals(Object obj) {
		if (obj == null){
			return false;
		}
		if (obj == this){
			return true;
		}
		if (this.getClass() != obj.getClass() ){
			return false;
		}
		final EqualsBuilder eqb = new EqualsBuilder();
		eqb.append(this.nombre, this.getClass().cast(obj).nombre);
		eqb.append(this.apellidos, this.getClass().cast(obj).apellidos);
		eqb.append(this.direccion, this.getClass().cast(obj).direccion);
		return eqb.isEquals();
	
	}

}

De esta implementación cabe destacar la forma como hemos definido el id de la entidad para que sea un autonumérico. Además hay que fijarse como hemos definido los métodos hashCode() y equals(), que nos evitarán problemas a la hora de trabajar con la persistencia.

9. Creando la clase de persistencia para la entidad Persona

Como ya hemos implementado el DAO genérico, para crear la clase que se va a encargar de la persistencia de la entidad Persona, va a ser tan sencillo como definir la siguiente interfaz:

package com.autentia.tutoriales.dao;

import com.autentia.tutoriales.model.Persona;

public interface PersonaDAO extends GenericDAO<Persona, Long>{

}

Y la implementación de la clase es tan sencillo como lo siguiente:

package com.autentia.tutoriales.dao.imp.jpa;

import org.springframework.stereotype.Repository;

import com.autentia.tutoriales.dao.PersonaDAO;
import com.autentia.tutoriales.model.Persona;

@Repository("personaDAO")
public class PersonaDAOJPAImpl extends GenericDAOJPAImpl<Persona, Long> implements PersonaDAO{

}

Cabe destacar la utilización de la anotación @Repository que nos ahorra tener que definir un bean explícito en el fichero application-context-model-tutoriales.xml.

Con esto la entidad Persona ya tiene disponibles los métodos del DAO genérico, en caso de necesitar otros métodos específicos, habría que implementarlos en la clase PersonaDAOJPAImpl y definirlos en la interfaz PersonaDAO.

10. Vamos a probarlo

A fin de probar esta implementación vamos a definir un archivo application-context.xml y pesistence.xml específicos para las pruebas, donde vamos a utilizar una base de datos en memoria.

Para ello vamos a crear el fichero application-context-model-tutoriales-test.xml dentro de la carpeta src/test/resources con el siguiente contenido:

  
  
      
  
      
  
      
  
      
          
      
  
      
          
      
  
      
  

La única diferencia con el anterior es la definición del fichero persistence-test.xml, que se almacena en la carpeta src/test/resources/META-INF con el siguiente contenido:

  
      
    org.hibernate.ejb.HibernatePersistence  
    com.autentia.tutoriales.model.Persona  
          
              
              
              
              
              
              
              
              
              
              
              
          
      

Una vez configurado el entorno de pruebas sólo tenemos que implementar la siguiente clase con JUnit, donde vamos a probar la inserción, recuperación, modificación y eliminación de un registro de la entidad Persona.

package com.autentia.tutoriales.dao.imp.jpa;

import javax.annotation.Resource;

import static org.junit.Assert.*;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.transaction.TransactionConfiguration;
import org.springframework.transaction.annotation.Transactional;

import com.autentia.tutoriales.dao.PersonaDAO;
import com.autentia.tutoriales.model.Persona;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "classpath:/application-context-model-tutoriales-test.xml" })
@Transactional
@TransactionConfiguration(defaultRollback=true)
public class PersonaDAOJPAImplTest {
	
	@Resource
	PersonaDAO personaDAO;
	
	@Test
	public void crudPersona(){
		Persona persona = new Persona();
		persona.setNombre("Nombre");
		persona.setApellidos("Apellidos");
		persona.setDireccion("Direccion");
		
		personaDAO.insert(persona);
		
		assertEquals(new Long(1), persona.getIdPersona());
		
		Persona personaRecuperada = personaDAO.findByPK(Persona.class, persona.getIdPersona());
		personaRecuperada.setApellidos("Apellidos modificado");
		
		personaDAO.update(personaRecuperada);
		
		personaRecuperada = personaDAO.findByPK(Persona.class, personaRecuperada.getIdPersona());
		assertEquals("Apellidos modificado", personaRecuperada.getApellidos());
		
		personaDAO.remove(personaRecuperada);
		
	}
	
}

La anotación @RunWith y @ContextConfiguration nos permiten levantar el contexto de Spring para que se produzca la inyección de la dependencia PersonaDAO.

11. Conclusiones

Hemos visto como crear una librería para acceder a un esquema de base de datos que podremos importar en cualquier proyecto que necesite trabajar con este esquema. De hecho yo voy a utilizarla en posteriores desarrollos de futuros tutoriales.

Saludos.

11 COMENTARIOS

  1. Hola Ruben, antes que nada quería agradecerte por el excelente tutorial, es muy claro y por sobre todo muy útil. Tengo un problema al querer realizar las pruebas, me sale un error en la carga del contexto de aplicación, revisé todo y se supone que esta todo bien. Podrías subir el código o decirme como puedo enviarte el mío para que me des una mano. Gracias. Saludos

  2. Hola Ruben igualmente muchas gracias por el tutorial, pero tengo el mismo error que Booger. Como podemos solucionar esto? Muchas Gracias!

  3. Ya corregi el error que tenia: la falla estaba en el Persistence.xml y el persistence-test.xml, no habia definido el nombre de mi base de datos en: tenia tutoriales. Espero que esto te sirva Booger

  4. Hola gracias por todo Ruben, pero me sale un error en la carga del contexto de aplicación. He leido intentado hacer otros tutoriales de esta sitio y siempre o los dejan a medias o con errores. Un consejo si van a dar tutoriales es porque lo van a leer personas que estan aprendiendo. Se hacen preguntas y nunca se responden. Que estes bien y gracias por el tuto.

  5. Hola gabohacker,

    ¿Podrías darme más información sobre cuál es el error que está dando? Por ejemplo, el log de la aplicación con la traza de la pila estaría genial.

    Saludos.

  6. 4/04/2011 04:59:38 PM org.springframework.test.context.TestContextManager retrieveTestExecutionListeners
    INFO: @TestExecutionListeners is not present for class [class com.urbanalab.modelo.pruebas.PersonaDAOJPAImplTest]: using defaults.
    4/04/2011 04:59:38 PM org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
    INFO: Loading XML bean definitions from class path resource [com/urbanalab/modelo/pruebas/applicationContext.xml]
    4/04/2011 04:59:38 PM org.springframework.context.support.AbstractApplicationContext prepareRefresh
    INFO: Refreshing org.springframework.context.support.GenericApplicationContext@4720d62b: startup date [Mon Apr 04 16:59:38 COT 2011]; root of context hierarchy
    4/04/2011 04:59:38 PM org.springframework.beans.factory.support.DefaultListableBeanFactory preInstantiateSingletons
    INFO: Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@687bc899: defining beans [org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalRequiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,org.springframework.context.annotation.internalPersistenceAnnotationProcessor,personaDAO,org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor#0,entityManagerFactory,transactionManager,org.springframework.aop.config.internalAutoProxyCreator,org.springframework.transaction.annotation.AnnotationTransactionAttributeSource#0,org.springframework.transaction.interceptor.TransactionInterceptor#0,org.springframework.transaction.config.internalTransactionAdvisor]; root of factory hierarchy
    4/04/2011 04:59:38 PM org.springframework.beans.factory.support.DefaultSingletonBeanRegistry destroySingletons
    INFO: Destroying singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@687bc899: defining beans [org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalRequiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,org.springframework.context.annotation.internalPersistenceAnnotationProcessor,personaDAO,org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor#0,entityManagerFactory,transactionManager,org.springframework.aop.config.internalAutoProxyCreator,org.springframework.transaction.annotation.AnnotationTransactionAttributeSource#0,org.springframework.transaction.interceptor.TransactionInterceptor#0,org.springframework.transaction.config.internalTransactionAdvisor]; root of factory hierarchy
    4/04/2011 04:59:38 PM org.springframework.test.context.TestContextManager prepareTestInstance
    GRAVE: Caught exception while allowing TestExecutionListener [org.springframework.test.context.support.DependencyInjectionTestExecutionListener@11e9c82e] to prepare test instance [com.urbanalab.modelo.pruebas.PersonaDAOJPAImplTest@b554d32]
    java.lang.IllegalStateException: Failed to load ApplicationContext
    at org.springframework.test.context.TestContext.getApplicationContext(TestContext.java:308)
    at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.injectDependencies(DependencyInjectionTestExecutionListener.java:109)
    at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.prepareTestInstance(DependencyInjectionTestExecutionListener.java:75)
    at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:321)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.createTest(SpringJUnit4ClassRunner.java:220)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner$1.runReflectiveCall(SpringJUnit4ClassRunner.java:301)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.methodBlock(SpringJUnit4ClassRunner.java:303)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:240)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:49)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184)
    at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
    at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:236)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:180)
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:49)
    at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
    Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name \\\’personaDAO\\\’ defined in file [C:\\\\Users\\\\Comba_Desarrollo1\\\\EclipseProjects\\\\Database\\\\target\\\\classes\\\\com\\\\urbanalab\\\\modelo\\\\PersonaDAOJPAImpl.class]: Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: entityManagerFactory or jpaTemplate is required
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1420)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:519)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456)
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:291)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:288)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:190)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:580)
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:895)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:425)
    at org.springframework.test.context.support.AbstractGenericContextLoader.loadContext(AbstractGenericContextLoader.java:84)
    at org.springframework.test.context.support.AbstractGenericContextLoader.loadContext(AbstractGenericContextLoader.java:1)
    at org.springframework.test.context.TestContext.loadApplicationContext(TestContext.java:280)
    at org.springframework.test.context.TestContext.getApplicationContext(TestContext.java:304)
    … 24 more
    Caused by: java.lang.IllegalArgumentException: entityManagerFactory or jpaTemplate is required
    at org.springframework.orm.jpa.support.JpaDaoSupport.checkDaoConfig(JpaDaoSupport.java:120)
    at org.springframework.dao.support.DaoSupport.afterPropertiesSet(DaoSupport.java:44)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1477)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1417)
    … 37 more

  7. Hola Rubén, felicidades, son muy buenas estas clases, espero que sigan ilustrandonos… Bueno, la implementacion de todo este codigo esta perfectamente, obviamente tambien a mi me vinieron errores, pero uno de los trabajos del programador es resolver los problemas que se presentan… Yo he resuelto modificando una dependencia en el pom.xml.
    Se debe sostituir la dependencia persistence-api-1.0.2 por hibernate-jpa-2.0-api, dejo el fragmento del pom con la modifica… Saludos y gracias 😉

    CODIGO DE ELIMINAR O COMENTAR

    javax.persistence
    persistence-api
    1.0.2

    DEPENDENCIA QUE SOSTITUYE LA ANTERIOR

    org.hibernate.javax.persistence
    hibernate-jpa-2.0-api
    1.0.1.Final

  8. Hola Rubén, felicidades, son muy buenas estas clases, espero que sigan ilustrandonos… Bueno, la implementacion de todo este codigo esta perfectamente, obviamente tambien a mi me vinieron errores, pero uno de los trabajos del programador es resolver los problemas que se presentan… Yo he resuelto modificando una dependencia en el pom.xml.
    Se debe sostituir la dependencia persistence-api-1.0.2 por hibernate-jpa-2.0-api, dejo el fragmento del pom con la modifica… Saludos y gracias 😉

    CODIGO DE ELIMINAR O COMENTAR
    groupId: javax.persistence
    artifactId: persistence-api
    version: 1.0.2

    DEPENDENCIA QUE SOSTITUYE LA ANTERIOR
    groupId: org.hibernate.javax.persistence
    artifactId: hibernate-jpa-2.0-api
    version: 1.0.1.Final

  9. Hola,

    Primero agredecer el tuto, está muy bastante clarito todo. Pero tengo el mismo problema que otros tantos aquí al lanzar el test y es que el contexto no se levanta correctamente y no se llega a inicializar el persistenceContext.

    ¿Alguna luz que arrojar sobre esto? Está todo ok según parece. Pongo el stack trace:

    java.lang.IllegalStateException: Failed to load ApplicationContext
    at org.springframework.test.context.TestContext.getApplicationContext(TestContext.java:308)
    at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.injectDependencies(DependencyInjectionTestExecutionListener.java:109)
    at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.prepareTestInstance(DependencyInjectionTestExecutionListener.java:75)
    at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:333)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.createTest(SpringJUnit4ClassRunner.java:220)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner$1.runReflectiveCall(SpringJUnit4ClassRunner.java:301)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.methodBlock(SpringJUnit4ClassRunner.java:303)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:240)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:49)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184)
    at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
    at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:236)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:180)
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
    at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
    Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name \\\’TaskDAO\\\’ defined in file [D:\\\\DEVEL\\\\git\\\\common-gateway\\\\persistence\\\\target\\\\classes\\\\eu\\\\ohim\\\\cfportal\\\\dao\\\\imp\\\\jpa\\\\TaskDAOJPAImpl.class]: Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: entityManagerFactory or jpaTemplate is required
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1420)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:519)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456)
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:291)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:288)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:190)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:580)
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:895)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:425)
    at org.springframework.test.context.support.AbstractGenericContextLoader.loadContext(AbstractGenericContextLoader.java:84)
    at org.springframework.test.context.support.AbstractGenericContextLoader.loadContext(AbstractGenericContextLoader.java:1)
    at org.springframework.test.context.TestContext.loadApplicationContext(TestContext.java:280)
    at org.springframework.test.context.TestContext.getApplicationContext(TestContext.java:304)
    … 24 more
    Caused by: java.lang.IllegalArgumentException: entityManagerFactory or jpaTemplate is required
    at org.springframework.orm.jpa.support.JpaDaoSupport.checkDaoConfig(JpaDaoSupport.java:120)
    at org.springframework.dao.support.DaoSupport.afterPropertiesSet(DaoSupport.java:44)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1477)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1417)
    … 37 more

  10. Buenas,

    Hice una prueba con un código pero me ha errores las lineas:
    import javax.persistence.EntityManager;
    import javax.persistence.EntityManagerFactory;
    import javax.persistence.Persistence;

    import org.junit.After;
    import org.junit.AfterClass;
    import org.junit.Assert;
    import org.junit.Before;
    import org.junit.BeforeClass;
    import org.junit.Test;

    Alguien me puede ayudar, parece que no localiza estas importaciones de clases.

    Un saludo;

    David

DEJA UNA RESPUESTA

Por favor ingrese su comentario!

He leído y acepto la política de privacidad

Por favor ingrese su nombre aquí

Información básica acerca de la protección de datos

  • Responsable:
  • Finalidad:
  • Legitimación:
  • Destinatarios:
  • Derechos:
  • Más información: Puedes ampliar información acerca de la protección de datos en el siguiente enlace:política de privacidad