icono_twiter icono LinkedIn
Rubén Aguilera Díaz-Heredero

Consultor tecnológico de desarrollo de proyectos informáticos.

Ingeniero en Informática, especialidad en Ingeniería del Software

Puedes encontrarme en Autentia: Ofrecemos servicios de soporte a desarrollo, factoría y formación

Somos expertos en Java/J2EE

Ver todos los tutoriales del autor

Fecha de publicación del tutorial: 2011-02-05

Tutorial visitado 15.760 veces Descargar en PDF
Librería de acceso a datos con Spring y JPA

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:



	<context:annotation-config />

	<context:component-scan base-package="com.autentia.tutoriales" />

	<bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" />

	
		<property name="persistenceXmlLocation" value="classpath:/META-INF/persistence.xml" />
	

	
		<property name="entityManagerFactory" ref="entityManagerFactory" />
	

	<tx:annotation-driven transaction-manager="transactionManager" />


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
    
      <property name="hibernate.connection.url" value="jdbc:postgresql:tutoriales"/>
      <property name="hibernate.connection.driver_class" value="org.postgresql.Driver"/>
      <property name="hibernate.connection.password" value="autentia"/>
      <property name="hibernate.connection.username" value="postgres"/>
      <property name="hibernate.cache.provider_class" value="org.hibernate.cache.NoCacheProvider"/>
      <property name="hibernate.dialect" value="org.hibernate.dialect.PostgreSQLDialect"/>
      <property name="hibernate.connection.pool_size" value="8"/>
      <property name="transaction.factory_class" value="org.hibernate.transaction.JDBCTransactionFactory"/>
      <property name="hibernate.format_sql" value="true"/>
      <property name="hibernate.hbm2ddl.auto" value="update"/>
    
  

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 <T, PK extends Serializable> {

    List<T> getAll(Class<T> typeClass);

    T findByPK(Class<T> typeClass, PK id);

    void update(T object);

    void remove(T object);

    void insert(T object);
    
    List<T> getPaginated(Class<T> typeClass, int startPosition, int maxResult);
    
    List<T> getOrderedPaginated(Class<T> 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:



	<context:annotation-config />

	<context:component-scan base-package="com.autentia.tutoriales" />

	<bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" />

	
		<property name="persistenceXmlLocation" value="classpath:/META-INF/persistence-test.xml" />
	

	
		<property name="entityManagerFactory" ref="entityManagerFactory" />
	

	<tx:annotation-driven transaction-manager="transactionManager" />


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
		
			<property name="hibernate.dialect" value="org.hibernate.dialect.HSQLDialect" />
			<property name="hibernate.hbm2ddl.auto" value="create" />
			<property name="hibernate.connection.driver_class" value="org.hsqldb.jdbcDriver" />
			<property name="hibernate.connection.username" value="sa" />
			<property name="hibernate.connection.password" value="" />
			<property name="hibernate.connection.url" value="jdbc:hsqldb:mem:tutoriales" />
			<property name="hibernate.showSql" value="true" />
			<property name="hibernate.format_sql" value="true"/>
			<property name="transaction.factory_class" value="org.hibernate.transaction.JDBCTransactionFactory"/>
			<property name="hibernate.cache.provider_class" value="org.hibernate.cache.NoCacheProvider"/>
			<property name="hibernate.connection.pool_size" value="8"/>
		
	

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.

A continuación puedes evaluarlo:

Regístrate para evaluarlo

Por favor, vota +1 o compártelo si te pareció interesante

Share |
Anímate y coméntanos lo que pienses sobre este TUTORIAL:

Fecha publicación: 2012-03-07-10:56:41

Autor: Sampel

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:DEVELgitcommon-gatewaypersistencetargetclasseseuohimcfportaldaoimpjpaTaskDAOJPAImpl.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

Fecha publicación: 2011-11-07-00:16:54

Autor: fumandito

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

Fecha publicación: 2011-11-06-23:37:15

Autor: fumandito

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
<dependency>
<groupId>javax.persistence</groupId>
<artifactId>persistence-api</artifactId>
<version>1.0.2</version>
</dependency>

DEPENDENCIA QUE SOSTITUYE LA ANTERIOR
<dependency>
<groupId>org.hibernate.javax.persistence</groupId>
<artifactId>hibernate-jpa-2.0-api</artifactId>
<version>1.0.1.Final</version>
</dependency>

Fecha publicación: 2011-07-07-23:56:51

Autor: m4m4n1

Simplemente excelente estimado Rubén, tiene la esencia de la solución.

Fecha publicación: 2011-04-05-00:03:34

Autor: gabohacker

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:UsersComba_Desarrollo1EclipseProjectsDatabasetargetclassescomurbanalabmodeloPersonaDAOJPAImpl.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

Fecha publicación: 2011-04-04-21:39:38

Autor: rubenagui

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.

Fecha publicación: 2011-04-04-16:39:26

Autor: gabohacker

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.

Fecha publicación: 2011-03-21-21:00:35

Autor: jossydeleon

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: <persistence-unit name="mi_database" transaction-type="RESOURCE_LOCAL"> tenia tutoriales. Espero que esto te sirva Booger

Fecha publicación: 2011-03-21-19:36:13

Autor: jossydeleon

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

Fecha publicación: 2011-02-07-22:09:59

Autor: Booger

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