Home > Solutions Log, Spring > Introduction to Spring Data JPA

Introduction to Spring Data JPA

The Spring Data JPA, a sub project of Spring Data is aimed at simplifying repository implementations. Repositories typically provide Create, Read, Update and Delete (CRUD) operations for domain objects. In this blog post, I will show how Spring Data JPA drastically reduces the effort needed to create repositories.

We will be using HSQLDB as the database and Hibernate as the JPA implementation provider. Here is a complete list project’s dependencies from Maven’s pom.xml file:


	<dependencies>	
		 <dependency>
			 <groupId>org.springframework.data</groupId>
	 		 <artifactId>spring-data-jpa</artifactId>
	 		 <version>1.1.0.RELEASE</version>
	 		 <exclusions>
	 		 	<exclusion>
					<groupId>org.slf4j</groupId>
					<artifactId>jcl-over-slf4j</artifactId>	 		 	
	 		 	</exclusion>
	 		 	</exclusions>
		</dependency>
		
		<dependency>
			<groupId>commons-logging</groupId>
			<artifactId>commons-logging</artifactId>
			<version>1.1.1</version>
		</dependency>
		
		<dependency>
			<groupId>cglib</groupId>
			<artifactId>cglib-nodep</artifactId>
			<version>2.1_3</version>
		</dependency>
		
		<dependency>
			<groupId>log4j</groupId>
			<artifactId>log4j</artifactId>
			<version>1.2.14</version>
		</dependency>
		
		<dependency>
			<groupId>aspectj</groupId>
			<artifactId>aspectjweaver</artifactId>
			<version>1.5.2a</version>
		</dependency>
		
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-test</artifactId>
			<version>3.1.2.RELEASE</version>
			<scope>test</scope>
		</dependency>
		
		<dependency>
			<groupId>org.hibernate</groupId>
			<artifactId>hibernate-entitymanager</artifactId>
			<version>4.1.0.Final</version>
		</dependency>
		
		<dependency>
			<groupId>org.hsqldb</groupId>
			<artifactId>hsqldb</artifactId>
			<version>2.2.8</version>
		</dependency>
		
	</dependencies>

Before we go about implementing repositories using Spring Data JPA, let’s create two domain objects Person and Address:


package com.inflinx.blog.springdata.domain;

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

@Entity
@Table(name="PERSON")
public class Person {

	@Id
	@GeneratedValue(strategy=GenerationType.IDENTITY)
	@Column(name="PERSON_ID")
	private Long id;

	@Column(name="FIRST_NAME")
	private String firstName;
	
	@Column(name="LAST_NAME")
	private String lastName;
	
	@Column(name="GENDER_CODE")
	private String genderCode;
		
	// Getters and Setters	
}

package com.inflinx.blog.springdata.domain;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;

@Entity
@Table(name="ADDRESS")
public class Address {
	
	@Id
	@GeneratedValue(strategy=GenerationType.IDENTITY)
	@Column(name="ADDRESS_ID")
	private int id;

	@Column(name="STREET")
	private String street;
	
	@Column(name="CITY")
	private String city;
	
	@Column(name="STATE")
	private String state;

	@Column(name="ZIPCODE")
	private int zipCode;
	
	@ManyToOne
	@JoinColumn(name="PERSON_ID")
	private Person person;
	
	// Getters and Setters
}	
	

Notice that the two domain classes have JPA annotations such as @Table and @Column that map these classes to relational tables. Also notice the Many To One relationship between Address and Person classes.

Simple JPA Repository

We now start by creating a Spring Data JPA repository for the Person class. This involves creating a repository interface as shown below. The PersonRepository interface extends the Spring Data JPA’s Repository marker interface and has one finder method. The findOne method follows Spring Data JPA’s naming convention for retrieving an entity using its ID.

package com.inflinx.blog.springdata.repository;

import org.springframework.data.repository.Repository;
import com.inflinx.blog.springdata.domain.Person;

public interface PersonRepository extends Repository < Person, Long > {
	public Person findOne(Long id);
}

Traditionally, we would also create an implementation class for this repository. However Spring Data JPA alleviates this need and provides an implementation class (proxy) automatically at runtime. For this to happen, we add the jpa:repositories bean declaration to our context file. Here is the complete context file:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:jdbc="http://www.springframework.org/schema/jdbc"
	xmlns:jpa="http://www.springframework.org/schema/data/jpa"
	xmlns:p="http://www.springframework.org/schema/p"
	xmlns:tx="http://www.springframework.org/schema/tx"
	xmlns:repository="http://www.springframework.org/schema/data/repository"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
		http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.1.xsd
		http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa-1.1.xsd
		http://www.springframework.org/schema/data/repository http://www.springframework.org/schema/data/repository/spring-repository-1.0.xsd
		http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd">
	
	<jdbc:embedded-database id="dataSource">
        <jdbc:script location="classpath:schema.sql"/>
        <jdbc:script location="classpath:test-data.sql"/>
    </jdbc:embedded-database>
    
	<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean" 
          p:data-source-ref="dataSource" p:persistence-xml-location="classpath:test-persistence.xml" p:jpaDialect-ref="jpaDialect">
    </bean>
    
    <tx:annotation-driven transaction-manager="transactionManager"/>  
       
	<bean id="jpaDialect" class="org.springframework.orm.jpa.vendor.HibernateJpaDialect" />
	
    <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager" 
          p:entity-manager-factory-ref="entityManagerFactory">
    </bean>
    
    <jpa:repositories base-package="com.inflinx.blog.springdata.repository" />
</beans>

The jdbc:embedded-database tag in the context file starts an in-memory database using HSQLDB and creates a datasource for it. The schema.sql file shown below has the DDL commands for creating the Person and Address table:

CREATE TABLE PERSON (PERSON_ID INT GENERATED ALWAYS AS IDENTITY PRIMARY KEY, 
					FIRST_NAME VARCHAR(256), 
					LAST_NAME VARCHAR(256), 
					GENDER_CODE VARCHAR(1));

CREATE TABLE ADDRESS(ADDRESS_ID INT GENERATED ALWAYS AS IDENTITY PRIMARY KEY, 
 					STREET VARCHAR(256), 
 					CITY VARCHAR(100), 
 					STATE VARCHAR(10), 
 					ZIPCODE INT,
 					PERSON_ID INT,
 					FOREIGN KEY (PERSON_ID) REFERENCES PERSON(PERSON_ID)); 

The test-data.sql file has the test data we will be using to test our repositories:

	INSERT INTO PERSON (FIRST_NAME, LAST_NAME, GENDER_CODE) VALUES ('John', 'Doe', 'M');
	INSERT INTO PERSON (FIRST_NAME, LAST_NAME, GENDER_CODE) VALUES ('Jane', 'Doe', 'F');
	INSERT INTO PERSON (FIRST_NAME, LAST_NAME, GENDER_CODE) VALUES ('Joe', 'Bloggs', 'M');

The entitiyManagerFactory bean uses test-persistence.xml file that has the standard JPA configuration.


<persistence xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
	xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd" version="2.0">

  <persistence-unit name="springdata" transaction-type="RESOURCE_LOCAL">
    <provider>org.hibernate.ejb.HibernatePersistence</provider>
    
    <class>com.inflinx.blog.springdata.domain.Person</class>
    <class>com.inflinx.blog.springdata.domain.Address</class>
    
    <properties>
      <property name="javax.persistence.jdbc.driver" value="org.hsqldb.jdbcDriver"/>
      <property name="hibernate.dialect" value="org.hibernate.dialect.HSQLDialect"/>
      <property name="hibernate.hbm2ddl.auto" value="update"/>
	  <property name="hibernate.show_sql" value="true"/>
	  <property name="hibernate.format_sql" value="true"/>
    </properties>
  </persistence-unit>
</persistence>

This completes all the setup needed for creating a Spring Data JPA repository. Now let’s create a JUnit test class to test our implementation.


package com.inflinx.blog.springdata.repository;

import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.TestExecutionListeners;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.support.DependencyInjectionTestExecutionListener;
import org.springframework.test.context.transaction.TransactionalTestExecutionListener;
import org.springframework.transaction.annotation.Transactional;

import com.inflinx.blog.springdata.domain.Person;

@RunWith(SpringJUnit4ClassRunner.class)
@TestExecutionListeners({DependencyInjectionTestExecutionListener.class, TransactionalTestExecutionListener.class})
@Transactional
@ContextConfiguration(locations = {"classpath:test-context.xml"})
public class PersonRepositoryTest {

	@Autowired
	private PersonRepository personRepository;
	
	@Test
	public void testPerson() {
		Person person = personRepository.findOne(1L);
		Assert.assertNotNull(person);
		System.out.println("First Name: " + person.getFirstName());
	}
	
}

Notice that we are simply injecting the PersonRepository implementation into the test. When you run the class, you should see that test has passed and “First Name: Jane” in your console.

CRUD JPA Repository

The above PersonRepository has only one finder method and might not be ideal for most real world cases. To address this, Spring Data JPA provides an aptly named CrudRepository interface that extends Repository interface and adds persistence, finder and delete methods. The table below lists some of the available CrudRepository methods:

save(S entity) Saves a given entity
save(Iterable entities) Saves all the given entities
findOne(ID id) Retrieves an entity by its id
exists(ID id) Checks if a given entity exists
findAll Returns all the entities
count Returns the number of all the entities
delete(ID id) Deletes an entity with the given id
delete(T entity) Delets a given entity

A new person repository interface that uses CrudRepository is given below.


package com.inflinx.blog.springdata.repository;

import org.springframework.data.repository.CrudRepository;

import com.inflinx.blog.springdata.domain.Person;

public interface PersonCrudRepository extends CrudRepository < Person, Long > {

}

Here is a JUnit test that tests the above repository:


package com.inflinx.blog.springdata.repository;

import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.annotation.Rollback;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.TestExecutionListeners;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.support.DependencyInjectionTestExecutionListener;
import org.springframework.transaction.annotation.Transactional;

import com.inflinx.blog.springdata.domain.Person;

@RunWith(SpringJUnit4ClassRunner.class)
@TestExecutionListeners({DependencyInjectionTestExecutionListener.class})
@Transactional
@ContextConfiguration(locations = {"classpath:test-context.xml"})
public class PersonCrudRepositoryTest {

	@Autowired
	private PersonCrudRepository personRepository;
	
	@Test
	@Rollback(false)
	public void testCreate() {
		Person p = new Person();
		p.setFirstName("Test");
		p.setLastName("Data");
		p.setGenderCode("M");
		
		p = personRepository.save(p);
		Assert.assertNotNull(p.getId());
		System.out.println("Created Id: " + p.getId());
	}	
}

Custom Finder Methods

Spring Data JPA makes it very easy to add new finder methods to repositories. For example, let’s say we want to retrieve all persons with a given last name. Here is the modified PersonCrudRepository repository with the new finder method:

package com.inflinx.blog.springdata.repository;

import java.util.List;
import org.springframework.data.repository.CrudRepository;
import com.inflinx.blog.springdata.domain.Person;

public interface PersonCrudRepository extends CrudRepository < Person, Long > {

	public List< Person > findByLastName(String lastName);
}

The convention for these finder methods is simply findByMemberName. It is also possible to combine multiple members into one finder method. So, findByLastNameAndFirstName(String lastName, String firstName) will find all persons with the given first name and last name.

Here is the JUnit test class to test the findByLastName method:

 

	@Test
	public void testFindByLastName() {
		
		List< Person > lastNameList = personRepository.findByLastName("Doe");
		Assert.assertEquals(2, lastNameList.size());
	}

Named Queries

The out of the box CRUD methods are sufficient for most cases. However, there are times where we might want to execute custom SQL Queries to retrieve data. For example, let’s say we want to count all the persons that have a given last name. To address such situations, Spring Data JPA provides a @Query annotation. Here is the new person repository with the @Query annotated method:

package com.inflinx.blog.springdata.repository;

import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.CrudRepository;

import com.inflinx.blog.springdata.domain.Person;

public interface PersonCrudRepository extends CrudRepository < Person, Long > {

	@Query("select count(p) from Person p where p.lastName = ?1")
	public Long getLastNameCount(String lastName);
	
}

Here is a test method for the above Query method:

	@Test
	public void testGetLastNameCount() {
		
		Long count = personRepository.getLastNameCount("Doe");
		Assert.assertEquals(2L, count.longValue());
	}

Custom Repository Implementation

For cases, where the out of the box repository implementations are not enough, Spring Data JPA makes it easy to provide custom implementations that would still integrate with the generic repository abstraction. To see this in action, let’s implement a custom Address repository. We start with a custom interface that declares the additional functionality.

package com.inflinx.blog.springdata.repository;

public interface AddressRepositoryCustom {
	
	public Long someRandomMethod();
	
}

The next step is to create a class that implements the custom functionality.

package com.inflinx.blog.springdata.repository.jpa;

import com.inflinx.blog.springdata.repository.AddressRepositoryCustom;

public class AddressRepositoryImpl implements AddressRepositoryCustom {

	public Long someRandomMethod() {
		return 143L;
	}
}

Finally, we create the AddressRepository interface that extends the custom interface as shown below:

public interface AddressRepository extends CrudRepository < Address, Long >, AddressRepositoryCustom {
	
}

Here is a test class that tests the custom method implementation:

package com.inflinx.blog.springdata.repository;

import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.TestExecutionListeners;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.support.DependencyInjectionTestExecutionListener;
import org.springframework.transaction.annotation.Transactional;

@RunWith(SpringJUnit4ClassRunner.class)
@TestExecutionListeners({DependencyInjectionTestExecutionListener.class})
@Transactional
@ContextConfiguration(locations = {"classpath:test-context.xml"})
public class AddressRepositoryCustomTest {
	
	@Autowired
	private AddressRepository personRepository;
	
	@Test
	public void testSomeMethod() {
		
		Assert.assertEquals(143L, personRepository.someRandomMethod().longValue());
	}
	
}

Spring Data JPA requires that you follow strict naming conventions when creating custom repository implementation (unless you provide additional configuration). For example, if the repository interface is AddressRepository, then the name of the custom interface should be AddressRepositoryCustom. If you don’t follow this convention, you will end up with errors similar to this:

Caused by: java.lang.IllegalArgumentException: Could not create query metamodel for method public abstract java.lang.Long com.inflinx.blog.springdata.repository.AddressRepositoryCustom.someRandomMethod()!
at org.springframework.data.jpa.repository.query.JpaQueryLookupStrategy$CreateQueryLookupStrategy.resolveQuery(JpaQueryLookupStrategy.java:92)
at org.springframework.data.jpa.repository.query.JpaQueryLookupStrategy$CreateIfNotFoundQueryLookupStrategy.resolveQuery(JpaQueryLookupStrategy.java:162)

  1. Bharat
    October 3rd, 2012 at 12:25 | #1

    Thanks for very nice tutorial !!!
    I have following problem. I hope you can help me. When I trying crud operation using service layer its giving me bean creation error. Its working fine if I do operation through ‘personRepository’. please help.my code is as follows

    public class PersonRepositoryTest {

    @Autowired
    private PersonService personService; // ITS NOT WORKING

    // private PersonRepository personRepository; // ITS WORKING

    @Test
    public void testSavePerson(){
    Person person = new Person();
    person.setFirstName(“Ramkumar”);
    person.setLastName(“Patel”);
    personService.save(person);
    }

    }

  2. October 3rd, 2012 at 20:11 | #2

    @Bharat,
    What is the error you are getting? Can you post the exception?

  3. Bharat
    October 5th, 2012 at 10:53 | #3

    @Sudha Belida
    I guess I am doing something wrong in configuration. please find below link for full source code : –

    https://www.box.com/s/n11ewh6supw37novb9um

    and the exception as follows….

    org.springframework.beans.factory.BeanCreationException: Error creating bean with name ‘com.bharat.patel.repository.PersonRepositoryTest’: Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.bharat.patel.service.PersonService com.bharat.patel.repository.PersonRepositoryTest.personService; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No matching bean of type [com.bharat.patel.service.PersonService] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:287)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1106)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireBeanProperties(AbstractAutowireCapableBeanFactory.java:374)
    at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.injectDependencies(DependencyInjectionTestExecutionListener.java:110)
    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:211)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner$1.runReflectiveCall(SpringJUnit4ClassRunner.java:288)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.methodBlock(SpringJUnit4ClassRunner.java:290)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:231)
    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:71)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:236)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:174)
    at org.apache.maven.surefire.junit4.JUnit4TestSet.execute(JUnit4TestSet.java:53)
    at org.apache.maven.surefire.junit4.JUnit4Provider.executeTestSet(JUnit4Provider.java:123)
    at org.apache.maven.surefire.junit4.JUnit4Provider.invoke(JUnit4Provider.java:104)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at org.apache.maven.surefire.util.ReflectionUtils.invokeMethodWithArray(ReflectionUtils.java:164)
    at org.apache.maven.surefire.booter.ProviderFactory$ProviderProxy.invoke(ProviderFactory.java:110)
    at org.apache.maven.surefire.booter.SurefireStarter.invokeProvider(SurefireStarter.java:175)
    at org.apache.maven.surefire.booter.SurefireStarter.runSuitesInProcessWhenForked(SurefireStarter.java:107)
    at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:68)
    Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.bharat.patel.service.PersonService com.bharat.patel.repository.PersonRepositoryTest.personService; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No matching bean of type [com.bharat.patel.service.PersonService] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:506)
    at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:87)
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:284)
    … 32 more
    Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No matching bean of type [com.bharat.patel.service.PersonService] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoSuchBeanDefinitionException(DefaultListableBeanFactory.java:952)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:821)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:735)
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:478)
    … 34 more
    Tests run: 1, Failures: 0, Errors: 1, Skipped: 0, Time elapsed: 9.952 sec <<< FAILURE!
    05.10.2012 18:41:53 *INFO * GenericApplicationContext: doClose – Closing org.springframework.context.support.GenericApplicationContext@3a7faad6: startup date [Fri Oct 05 18:41:44 BST 2012]; root of context hierarchy – (AbstractApplicationContext.java, line 1025)
    05.10.2012 18:41:53 *INFO * DefaultListableBeanFactory: destroySingletons – Destroying singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@4cedd1e2: 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,dataSource,entityManagerFactory,jpaDialect,transactionManager,org.springframework.aop.config.internalAutoProxyCreator,org.springframework.transaction.annotation.AnnotationTransactionAttributeSource#0,org.springframework.transaction.interceptor.TransactionInterceptor#0,org.springframework.transaction.config.internalTransactionAdvisor,personRepository,org.springframework.data.repository.core.support.RepositoryInterfaceAwareBeanPostProcessor#0,org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor#0,org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor#0,org.springframework.context.annotation.ConfigurationClassPostProcessor$ImportAwareBeanPostProcessor#0]; root of factory hierarchy – (DefaultSingletonBeanRegistry.java, line 433)
    05.10.2012 18:41:53 *INFO * LocalContainerEntityManagerFactoryBean: destroy – Closing JPA EntityManagerFactory for persistence unit 'SpringData-Jpa' – (AbstractEntityManagerFactoryBean.java, line 441)

    Results :

    Tests in error:
    testSavePerson(com.bharat.patel.repository.PersonRepositoryTest): Error creating bean with name 'com.bharat.patel.repository.PersonRepositoryTest': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.bharat.patel.service.PersonService com.bharat.patel.repository.PersonRepositoryTest.personService; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No matching bean of type [com.bharat.patel.service.PersonService] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}

    Tests run: 2, Failures: 0, Errors: 1, Skipped: 0

  4. bharat
    October 5th, 2012 at 12:10 | #4

    @Sudha Belida

    please find below source code for full source code.

    https://www.box.com/s/s0u2il480gawc6qm6ry4

    The exception I got is..

    org.springframework.beans.factory.BeanCreationException: Error creating bean with name ‘com.bharat.patel.repository.PersonRepositoryTest’: Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.bharat.patel.service.PersonService com.bharat.patel.repository.PersonRepositoryTest.personService; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No matching bean of type [com.bharat.patel.service.PersonService] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:287)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1106)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireBeanProperties(AbstractAutowireCapableBeanFactory.java:374)
    at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.injectDependencies(DependencyInjectionTestExecutionListener.java:110)
    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:211)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner$1.runReflectiveCall(SpringJUnit4ClassRunner.java:288)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.methodBlock(SpringJUnit4ClassRunner.java:290)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:231)
    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:71)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:236)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:174)
    at org.apache.maven.surefire.junit4.JUnit4TestSet.execute(JUnit4TestSet.java:53)
    at org.apache.maven.surefire.junit4.JUnit4Provider.executeTestSet(JUnit4Provider.java:123)
    at org.apache.maven.surefire.junit4.JUnit4Provider.invoke(JUnit4Provider.java:104)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at org.apache.maven.surefire.util.ReflectionUtils.invokeMethodWithArray(ReflectionUtils.java:164)
    at org.apache.maven.surefire.booter.ProviderFactory$ProviderProxy.invoke(ProviderFactory.java:110)
    at org.apache.maven.surefire.booter.SurefireStarter.invokeProvider(SurefireStarter.java:175)
    at org.apache.maven.surefire.booter.SurefireStarter.runSuitesInProcessWhenForked(SurefireStarter.java:107)
    at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:68)
    Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.bharat.patel.service.PersonService com.bharat.patel.repository.PersonRepositoryTest.personService; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No matching bean of type [com.bharat.patel.service.PersonService] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:506)
    at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:87)
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:284)
    … 32 more

    Thanks for your help in advance

  5. October 5th, 2012 at 20:25 | #5

    @bharat
    I noticed that you forgot to add this to your appContext.xml file:

    <context:component-scan base-package=”com.bharat.patel.service” />

    Try this and it should fix your issue.

  6. Bharat
    October 6th, 2012 at 03:17 | #6

    Thanks Sudha,
    I found the solution.

    It was and the correct base package should be.

    please delete duplicate comments by me on your blog.
    Anyways thanks for your help such a nice tutorial !!!

  7. Digesh
    January 30th, 2013 at 05:06 | #7

    Hi My Service interface and implementation are in different packages. So in that case what can be done?

  8. Silver Mist
    February 7th, 2013 at 04:31 | #8

    Nice tutorial can you show a snapshot of the packaging structure, in a maven spring project i am trying to load the applicationContext-test.xml from another package(src/test/resoucres) it is not loading.

  9. Arya
    July 29th, 2013 at 11:29 | #9

    Hi
    I am new to spring JPA. Could you please provide an example if i want to retrieve data from multiple tables instead of one table? In that case how to create domain objects and establaish the relation between them.

  10. Tia
    November 5th, 2013 at 07:32 | #10

    Nice article :) Thanks !

  11. nabil
    April 8th, 2014 at 14:16 | #11

    great tutorial, many thanks :)

  1. No trackbacks yet.