Marketplace for Content, Tests and Assessment
 
 
Home > Programming / tutorials > Spring JPA Tutorial – Get Hands on Experience

Spring JPA Tutorial – Get Hands on Experience

Following we demonstrate you how a simple user contact information is saved using Spring and JPA. We use Hibernate as JPA provider.

Spring is a container which supports multiple frameworks and multiple services. Spring wraps the services and the frameworks together.

Spring’s Basic concept: Inversion of Control

The basic concept of spring is the Inversion of Control pattern (dependency injection). In Spring, programmers don’t need to create user objects but they need to describe how they should be created (in applicationContext.xml or using annotations). Programmers need not directly connect components and services together in code but describe which services are needed by which components in a configuration file or using annotations. The spring container is responsible for all this. Spring creates all the objects, connects them together by setting the necessary properties, and determines when methods will be invoked.

Requirements:

  1. Spring 2.0  – Download spring from http://www.springsource.org/download
  2. Hibernate 3 -  Download Hibernate from https://www.hibernate.org/30.html
  3. Eclipse 3 or Myeclipse 6
  4. Mysql Database

The major parts of the Contact application explained below are:

  1. The Entity classes
  2. The DAO class which will contain common db operation code and functions
  3. The service class – which is the actual business class.. This will contain actual business logic in it. In our example, we save contact information using this class.
  4. The client – The client can be a jsp / jsf  web components or it can be a simple java program, which getsthe service bean from spring and calls business method.
  5. The spring’s applicationContext.xml descriptor which specifies what are the objects to be created when starting the application and where they should be injected.

Let’s go through the tutorial step by step.You can download the full project code at the end of the tutorial:

 

Create a java project

Start eclipse. Select new  –> java project

springTut1

Specify a name (SpringJPATest) for the project.

springTut2

No you can see a Java project being created.

Create a folder by name lib under the SpringJPATest project. (Select the new created project rightclick )

springTut3

springTut4

Extract the downloaded spring and hibernate zips and copy the jars from the extracted directories to this lib directory.

Following are the jars required for the project

mysql-connector-java-5.1.5-bin.jar

activation.jar

antlr.jar

aopalliance.jar

asm.jar

asm-commons.jar

asm-util.jar

c3p0-0.9.1.jar

cglib-nodep.jar

commons-attributes.jar

commons-beanutils.jar

commons-codec.jar

commons-collections.jar

commons-digester.jar

commons-discovery.jar

commons-lang.jar

commons-logging.jar

commons-validator.jar

concurrent-1.3.2.jar

connector.jar

dom4j-1.6.1.jar

dsn.jar

ejb3-persistence.jar

hibernate.jar

hibernate-annotations.jar

hibernate-entitymanager.jar

hibernate-tools.jar

imap.jar

javassist.jar

jbossall-client.jar

jboss-archive-browsing.jar

jboss-aspect-library-jdk50.jar

jbosscx-client.jar

jboss-ejb3.jar

log4j-1.2.14.jar

pop3.jar

serializer.jar

smtp.jar

spring.jar

standard.jar

xalan.jar

xerces-2.6.2.jar

xercesImpl.jar

xml-apis.jar

Copy these jars into the lib directory

To compile the spring /JPA programs, the jars should be in the build path.
Select the project right click  –>  select ‘properties’

springTut5

Select ‘Java Build path’

springTut6

Click ‘add jars’, select the ‘SprongJPATest’ project and select all jars inside.

springTut7

Click OK.

springTut8

You can see the libraries being added to your path:

Database setup:

From this tutorial we simply demonstrate how you can persist the data into db using spring framework.

So first is to define a Contact Entity.

For this create a database and create tables into it (say contacts table)

Create table CONTACT(
ID int(15) not null auto_increment,
FIRSTNAME varchar(50) ,
LASTNAME varchar(50),
EMAIL varchar(150),
Primary key(id));

Create package:  com.test.entities and add a class by name ContactEO and copy the following contenets:

package com.test.entities;

import javax.persistence.Entity;

import javax.persistence.Table;

 

import javax.persistence.Column;

import javax.persistence.Entity;

import javax.persistence.Id;

import javax.persistence.Table;

import javax.persistence.*;

@Entity

@Table(name=”contact”)

 

public class ContactEO {

            private String firstName;

            private String lastName;

            private String email;

            private long id;

           

            @Column(name=”FIRSTNAME”)

            public String getFirstName() {

                        return firstName;

            }

           

            public void setFirstName(String string) {

                        firstName = string;

            }

           

            @Column(name=”LASTNAME”)

            public String getLastName() {

                        return lastName;

            }

           

            public void setLastName(String string) {

                        lastName = string;

            }

           

            @Column(name=”EMAIL”)

            public String getEmail() {

                        return email;

            }

            public void setEmail(String string) {

                        email = string;

            }

           

            @Id

            @GeneratedValue(strategy = GenerationType.IDENTITY)

            @Column(name=”ID”)

            public long getId() {

                        return contact.getId();

            }

           

            public void setId(long id) {

                        contact.setId(id);

            }

 

}

This project uses the JPA. The best feature of JPA and annotations is you don’t have to list the entitiy classes in any xml file. It scans the project and finds the classes annotated with @Entity.

Create package by name com.test.vo and add fllowing 2 calsses.

package com.test.vo;

public interface Contact {
 
 public String getFirstName();
 public void setFirstName(String firstName);
 
 public String getLastName();
 public void setLastName(String lastName);
 
 public String getEmail();
 public void setEmail(String email);
 
 public long getId();
 public void setId(long id);
 
}

 

and

package com.test.vo;

public class ContactVO implements Contact{
 private String firstName;
 private String lastName;
 private String email;
 private long id;
 public String getFirstName() {
  return firstName;
 }
 public void setFirstName(String firstName) {
  this.firstName = firstName;
 }
 public String getLastName() {
  return lastName;
 }
 public void setLastName(String lastName) {
  this.lastName = lastName;
 }
 public String getEmail() {
  return email;
 }
 public void setEmail(String email) {
  this.email = email;
 }
 public long getId() {
  return id;
 }
 public void setId(long id) {
  this.id = id;
 }
 
 
}

 

For JPA (with hibernate ) we specify the db and other database mapping information in META-INF/persistence.xml file. Generally we have to explicitly initialized the Hibernate sessionFactory , which intern created datasources, initialize pooling, maps entities etc  But as we are using with spring here, we configure the spring’s applicationContext.xml to specify which are the objects need to be initialized when starting the application.   Spring’s features initializes the hibernate SessionFacetory, the c3p pool required by it, the datasources to the db etc.  (Expllained later)

Creating DAO classes

Now let’s create DAO class. In Simple words DAO class is the one which has common methods used to access db like saving, finding all the records, deleting a record or updating etc. These are common operations on any table. We can group all of them together and put them in DAO class. It helps us avoiding the usage of repeating code in our service classes.

Here we are defining DAO class specific to the Contact entity. One can have generic DAO class where the type of the eo class can be sent as a parameter so that it can be used by all the eo classes.

Create a package by name com.test.dao, create a class by name ContactDAO and copy following code to it:

package com.test.dao;

 

import javax.persistence.EntityManager;

import javax.persistence.PersistenceContext;

 

import org.springframework.stereotype.Component;

import org.springframework.stereotype.Repository;

 

import com.test.entities.ContactEO;

 

 

@Repository

@Component

 

public class ContactDAO {

    @PersistenceContext

    private EntityManager entityManagerFactory;

    public void addContact(ContactEO contactEO){

            this.entityManagerFactory.persist(contactEO);

    }

   

}

Here we specify 2 annotations:

@Repository

@Component

@Repository annotation indicates that the class is operating as a repository (a.k.a. Data Access Object or DAO)

At runtime, with some configuration in applicationContext.xml file (which we describe later) this class will be automatically becomes managed by the spring. It will be instantiated and saved  It can be then injected into the service classes directly.

@Component specifies that the bean is a spring managed component.

In DAO class we define the Entiny manager. This will get  injected automatically.

@PersistenceContext

private EntityManager entityManagerFactory;

Now we will define the business class which will be actually called by other clients. Here we are not exposing the DAO classes. We are creating a service layer on top of it to do the business operations for the client. Client will not be aware of other db specific tasks done at service layer side.

For service layer. we first define an interface, which defines common methods and then implement the methods in a class. Interface can be used by service provider to expose their service functions.

Create a package called com.test.service create an interface by name ContactService and copy following contenets to it:

 package com.test.service;

 import org.springframework.stereotype.Component;

 import com.test.vo.Contact;

 public interface ContactService {

      public void addContactInformation(Contact contact);

}

Now we create service implementation:

Create a file by name ContactServiceImpl in same package: com.test.service and copy following contents:

package com.test.service;

 

import org.apache.commons.logging.Log;

import org.apache.commons.logging.LogFactory;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.transaction.annotation.Transactional;

import com.test.dao.ContactDAO;

import com.test.entities.ContactEO;

import com.test.vo.Contact;

 

public class ContactServiceImpl implements ContactService{

      @Autowired

      ContactDAO contactDAO;

     

     

      private final Log log = LogFactory.getLog(this.getClass());

     

      @Transactional(readOnly = false)

      public void addContactInformation(Contact contact){

            try {

                  // construct the Entity bean

                  ContactEO contactEO = new ContactEO(contact);

                 

                  // save it

                  contactDAO.addContact(contactEO);

            } catch (Exception e) {

                  e.printStackTrace();

                  log.fatal(“Problem in prepareDataForUpdate while comparing persistent data with the csv file data”, e);

            }

      }

}

Here we don’t instantiate the DAO class. We just annotate it with @Autowired. Spring will inject the DAO instance automatically.

Project Configuration – JPA configuration:

Create a file named jdbc.properties and copy following contents:

jdbc.driverClass=com.mysql.jdbc.Driver

jdbc.url=jdbc:mysql://localhost:3306/hibernatetest?autoReconnect=true

jdbc.username=root

jdbc.password=root

jdbc.database=MYSQL

jdbc.showSql=true

Here replace the jdbc url string’s db name and port etc according to your mysql settings

Replace

jdbc.username=root

jdbc.password=root

With your mysql username and properties value

Create a META-INF directory under src directory and create a file by name persistence.xml

Copy following contents:

<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_1_0.xsd”

            version=”1.0″>

      <persistence-unit name=”default” transaction-type=”RESOURCE_LOCAL”>

      </persistence-unit>

</persistence>

Here we are not specifying the database related information. This we do in spring’s applicationContext.xml file, which starts Hibernate and initializes the persistence unit for us at runtime.

Spring configuration:

Now We have to specify about the db settings, and bean components to spring, which we do using applicationContext.xml. Create a file by name applicationContext.xml in src directory. thisfile looks like below.

<?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:p=”http://www.springframework.org/schema/p” xmlns:aop=”http://www.springframework.org/schema/aop”

            xmlns:context=”http://www.springframework.org/schema/context” xmlns:jee=”http://www.springframework.org/schema/jee”

            xmlns:tx=”http://www.springframework.org/schema/tx”

            xsi:schemaLocation=”

                  http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd

                  http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd

                  http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd

                  http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-2.5.xsd

                  http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd”>

       <context:property-placeholder location=”classpath:jdbc.properties”/>

 

      <!– Connection Pool –>

      <bean id=”dataSource” destroy-method=”close”>

        <property name=”driverClass” value=”${jdbc.driverClass}”/>

        <property name=”jdbcUrl” value=”${jdbc.url}”/>

        <property name=”user” value=”${jdbc.username}”/>

        <property name=”password” value=”${jdbc.password}”/>

    </bean>

 

      <!– JPA EntityManagerFactory –>

      <bean id=”entityManagerFactory”

                  p:dataSource-ref=”dataSource”>

            <property name=”jpaVendorAdapter”>

                  <bean>

                          <property name=”database” value=”${jdbc.database}”/>

                              <property name=”showSql” value=”${jdbc.showSql}”/>                       

            </bean>          

            </property>

      </bean>

 

      <!– Transaction manager for a single JPA EntityManagerFactory (alternative to JTA) –>

      <bean id=”transactionManager”

                  p:entityManagerFactory-ref=”entityManagerFactory”/>

                 

      <!– Activates various annotations to be detected in bean classes for eg @Autowired–>

      <context:annotation-config/>

     

        <!– enable the configuration of transactional behavior based on annotations  –>

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

 

      <!– Property Configurator –>

    <bean id=”propertyConfigurer”>

            <property name=”location” value=”jdbc.properties”/>

      </bean>

   

 

   

    <context:component-scan base-package=”com.test.dao”/>

       

    <bean id=”contactService”/>

       

</beans>

How does spring finds its components?

By <bean id="dataSource" destroy-method="close">

We specify spring to initialize datasource c3p pooling(which is used by Hibernate)

By <bean id="entityManagerFactory" p:dataSource-ref="dataSource">

We specify the spring to initialize Hibernate.

<context:component-scan base-package="com.test.dao"/>

We tesll spring to scan the specified package and get components to be instantiated.

<context:annotation-config/>

This causes the spring to search for @Autowired annotation and inject the bean instance.

Also we specify to instantiate service class ContactServiceImpl whose ID is contactService.

Now copy log4j.properties (download from http://www.skill-guru.com/blog/wp-content/uploads/2009/10/log4j.properties) file into the src directory

Now we have successfully written the service class and configured spring. Lets write a client code to save a contact data using the service class:

package com.test.test;

import org.apache.commons.logging.Log;

import org.apache.commons.logging.LogFactory;

import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.test.service.ContactService;

import com.test.vo.Contact;

import com.test.vo.ContactVO;

public class TestContact {

            /** logging variable */

            private static final Log log = LogFactory.getLog(TestContact.class);

            public static void main(String args[]){

                        ContactService contactService ;

                        log.info(” Starting the ClinicSubnet Component batch updation process on “+new java.util.Date());

                ClassPathXmlApplicationContext appContext = new ClassPathXmlApplicationContext(new String[] {

                        “applicationContext.xml”

                    });

                contactService = (ContactService) appContext.getBean(“contactService”);

                Contact contact = new ContactVO();

                contact.setFirstName(“Smitha”);

                contact.setLastName(“Rao”);

                contact.setEmail(“smitha.h.rao@gmail.com”);

                contactService.addContactInformation(contact);

            }

}

Run the above code as java application. You can see the data being saved in the contact table.

 

To download the full code please click here

  1. Dennis
    October 14th, 2009 at 20:21 | #1

    Are you missing some packages & classes, like ContactVO?

  2. smitha
    October 14th, 2009 at 22:20 | #2

    Sorry @Dennis, Yes the ContactVO class and Contact interface were missing. I have added them right after the EO class. Also you can download the full code at the end of the tutorial.
    Thanks for the correction.

  3. Ganeshkumar
    June 4th, 2010 at 22:02 | #3

    Excellent and easy to understand

  1. October 19th, 2009 at 09:51 | #1
Get Adobe Flash playerPlugin by wpburn.com wordpress themes