Spring-Data-JPA

Implementing persistence layer may need some effort to configure and develop some DAO classes.

Spring-Data-JPA framework can simplify the creation of JPA based repositories and to reduce the amount of code needed to communicate with a database

   

Photo credit Ivan Kmit

This post is an introduction to Spring-Data-JPA. It describes, how you can configure the framewok when you are using Hibernate as your JPA provider.
In this post I will take profit from some Spring 4 new feature as generics autowiring to create generic service.
You can get the sample project from this link to start using Spring-Data-jpa and try some more advenced features.

1- Project dependencies

Spring-Data-JPA references a Spring 3 version. Maven will resolve dependencies by using Spring 3 version instead of version 4.

We need to exclude spring-core and spring-context and import Spring 4 version.


   <!-- Spring -->
   <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context</artifactId>
      <version>4.0.4.RELEASE</version>
   </dependency>
   <dependency>
      <groupId>org.springframework.data</groupId>
      <artifactId>spring-data-jpa</artifactId>
      <version>1.5.2.RELEASE</version>
      <exclusions>
         <exclusion>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
         </exclusion>
         <exclusion>
            <artifactId>spring-context</artifactId>
            <groupId>org.springframework</groupId>
         </exclusion>
     </exclusions>
   </dependency>

2- Add an Entity

@Entity
@Table(name = "users")
public class User {

    @Id
    @GenericGenerator(name = "generator", strategy = "increment")
    @GeneratedValue(generator = "generator")
    @Column(name = "id", nullable = false)
    private Long id;

    @Column(name = "first_name", nullable = false)
    private String firstName;

    /* Add some extra attributes */     

    /* Add getters and setters */

}

3- Create repository

Declare an interface extending Repository.

import com.mycompany.myproject.persist.entity.User;
import org.springframework.data.jpa.repository.JpaRepository;

public interface UserRepo extends JpaRepository<User, Long> {

    User findByLogin(String login);

}

Spring-Data-JPA analyses the method name and generates a query using the JPA criteria.
Query generation is base on key words like (And, Or, Is, Equals, Between …). For more details, you can read the official Spring-Data-JPA documentation in this link.

4- Create Service

We make a choice to create a generic service that will reference the repository created in previous step.

One of the new features of Spring4 is generic types qualifier. We will take profit from this feature to inject repository by its generic interface.

public class GenericServiceImpl<T, D, ID extends Serializable> implements GenericService<T, D, ID> {

    @Autowired
    private JpaRepository<T, ID> repository;

    @Autowired
    private DozerBeanMapper mapper;

    protected Class<T> entityClass;

    protected Class<D> dtoClass;

    @SuppressWarnings("unchecked")
    public GenericServiceImpl() {
        ParameterizedType genericSuperclass = (ParameterizedType) getClass().getGenericSuperclass();
        this.entityClass = (Class<T>) genericSuperclass.getActualTypeArguments()[0];
        this.dtoClass = (Class<D>) genericSuperclass.getActualTypeArguments()[1];
    }

    public D findOne(ID id) {
        return mapper.map(repository.findOne(id), dtoClass);
    }

    public List<D> findAll() {
        List<D> result = new ArrayList<D>();
        for (T t : repository.findAll()) {
            result.add(mapper.map(t, dtoClass));
        }
        return result;
    }
    
    public void save(D dto) {
        repository.saveAndFlush(mapper.map(dto, entityClass));
    }

}

Next, we add UserService that extends GenericServcie.

@Service
public class UserServiceImpl extends GenericServiceImpl<User, UserDto, Long> {
}

5- Configure the project

  • line 15 : EnableJpaRepositories annotation enables scanning package to look for repository interfaces (created in staep 3).
  • line 21 : We use HSQL embedded database. We need to provide schema script and data script.

import javax.sql.DataSource;
import org.dozer.DozerBeanMapper;
import org.springframework.context.annotation.*;
import org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.jdbc.datasource.embedded.*;
import org.springframework.orm.jpa.*;
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;

@Configuration
@EnableTransactionManagement
@ComponentScan({"com.mycompany.myproject.persist", "com.mycompany.myproject.service"})
@EnableJpaRepositories("com.mycompany.myproject.persist")
public class JPAConfig {

    @Bean(name = "dataSource")
    public DataSource dataSource() {
        return new EmbeddedDatabaseBuilder().setType(EmbeddedDatabaseType.HSQL).setName("myDb")
                .addScript("classpath:schema.sql").addScript("classpath:data.sql").build();
    }

    @Bean(name = "entityManagerFactory")
    public LocalContainerEntityManagerFactoryBean entityManagerFactoryBean() {
        LocalContainerEntityManagerFactoryBean factoryBean = new LocalContainerEntityManagerFactoryBean();
        factoryBean.setDataSource(dataSource());
        factoryBean.setPackagesToScan(new String[] { "com.mycompany.myproject.persist" });
        HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
        vendorAdapter.setShowSql(true);
        factoryBean.setJpaVendorAdapter(vendorAdapter);
        return factoryBean;
    }

    @Bean
    public PlatformTransactionManager transactionManager() {
        JpaTransactionManager transactionManager = new JpaTransactionManager();
        transactionManager.setEntityManagerFactory(entityManagerFactoryBean().getObject());
        return transactionManager;
    }

    @Bean
    public PersistenceExceptionTranslationPostProcessor exceptionTranslation() {
        return new PersistenceExceptionTranslationPostProcessor();
    }

    @Bean
    public DozerBeanMapper getMapper() {
        return new DozerBeanMapper();
    }
}

6- Test your application

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {JPAConfig.class })
public class GenericServiceTest {
	
	@Autowired
	private GenericService<User, UserDto, Long> userService;
	
	@Autowired
    private GenericService<Authority, AuthorityDto, Long> authorityService;
	
	@Test
	public void testFindOneUser() {
		UserDto userDto = userService.findOne(1L);
		Assert.assertNotNull(userDto);
		Assert.assertEquals(1, userDto.getId().longValue());
	}
	
	@Test
    public void testFindOneAuthority() {
        AuthorityDto authorityDto = authorityService.findOne(1L);
        Assert.assertNotNull(authorityDto);
        Assert.assertEquals(1, authorityDto.getId().longValue());
    }
	
	@Test
    public void testFindAll() {
        List<AuthorityDto> authorities = authorityService.findAll();
        Assert.assertFalse(authorities.isEmpty());
    }
	
	@Test
    public void testSave() {
        AuthorityDto authorityDto = new AuthorityDto();
        authorityDto.setName("test authority");
    }
}


If you are a concise code adept you will appreciate using Spring-Data-JPA. To get your repositories you just need to add some interfaces for entities. You don’t need to write redundant basic code for each persistent bean.

The mix of Spring-DATA-JPA and Spring4 gives some extra possibilities to write generic code for the persistence layer.

Advertisements

Using JSF RichFaces with Spring and JPA

JSF (Java Server Faces) is the most serious successor to the famous Struts Framework. It has a large success and it is adopted in most of the recent JEE projects. JSF is a standard and it has very strong community and industry support.

JSF is a MVC (Model-View-Controller) web framework based on component driven UI design model. It allows developers to concentrate on application business logic rather than on little details of HTML.

   

Photo credit: st_dimov

Many libraries come to extend JSF framework with Ajax components to help creating rich user interfaces. The most used libraries are :

    RichFaces ( JBoss project)
    ICEfaces (ICEsoft project)
    MyFaces (Apache project)

In this article, I present a project example to explain, in first step, how to integrate JSF with Spring and JPA and, in second step, how to use RichFaces to enhance the application interface.

1 – Create a basic JSF project

You can browse the source code of the project example in this link or you can checkout the project source code from Google SVN repository in this URL https://project4example2.googlecode.com
/svn/trunk
. After you check out the project into your IDE, the project will be structured as shown in the picture.

1.1 – Add JSF dependencies

To add JSF support to the application, you need to add some dependencies to the pom.xml file as shown in the source code bellow.

	....
	<dependencies>
		.......
		<dependency>
			<groupId>javax.faces</groupId>
			<artifactId>jsf-impl</artifactId>
			<version>1.2_08</version>
		</dependency>

		<dependency>
			<groupId>javax.faces</groupId>
			<artifactId>jsf-api</artifactId>
			<version>1.2_08</version>
		</dependency>

		<dependency>
			<groupId>javax.servlet</groupId>
			<artifactId>jstl</artifactId>
			<version>1.1.2</version>
			<scope>compile</scope>
		</dependency>
		
		<dependency>
			<groupId>com.sun.facelets</groupId>
			<artifactId>jsf-facelets</artifactId>
			<version>1.1.14</version>
		</dependency>

		<dependency>
			<groupId>javax.el</groupId>
			<artifactId>el-api</artifactId>
			<version>1.0</version>
			<scope>provided</scope>
		</dependency>

		<dependency>
			<groupId>el-impl</groupId>
			<artifactId>el-impl</artifactId>
			<version>1.0</version>
			<scope>provided</scope>
		</dependency>
		......
	<dependencies>
   

1.2 – Add JSF configuration to web.xml file

FacesServlet must be configured in web.xml, it is the central controller for the JSF application. It receives all requests for the JSF application and initializes the JSF components before the JSP or XHTML is displayed.

	......
	<context-param>
		<param-name>javax.faces.DEFAULT_SUFFIX</param-name>
		<param-value>.xhtml</param-value>
	</context-param>

	<servlet>
		<servlet-name>Faces Servlet</servlet-name>
		<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
		<load-on-startup>1</load-on-startup>
	</servlet>

	<servlet-mapping>
		<servlet-name>Faces Servlet</servlet-name>
		<url-pattern>*.jsf</url-pattern>
	</servlet-mapping>
	......

1.3 – Create faces-config.xml file

faces-config.xml allows to configure the application, managed beans, convertors, validators, and navigation rules.

<?xml version="1.0" encoding="UTF-8"?>
<faces-config version="1.2" xmlns="http://java.sun.com/xml/ns/javaee"
	xmlns:xi="http://www.w3.org/2001/XInclude" 
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
http://java.sun.com/xml/ns/javaee/web-facesconfig_1_2.xsd">
	
	<managed-bean>
		<description>customer</description>
		<managed-bean-name>customer</managed-bean-name>
		<managed-bean-class>
			com.mycompany.bean.CustomerController
		</managed-bean-class>
		<managed-bean-scope>request</managed-bean-scope>
		<managed-property>
			<property-name>customerDao</property-name>
			<value>#{customerDao}</value>
		</managed-property>
	</managed-bean>
	
	<application>
		<locale-config>
            <default-locale>en</default-locale>
        </locale-config>
		
		<message-bundle>messages</message-bundle>
		
		<el-resolver>org.springframework.web.jsf.el.SpringBeanFacesELResolver</el-resolver>
	</application>
</faces-config>

In the faces-config.xml, we specify SpringBeanFacesELResolver as el-resolver (Expression Language Resolver). The #{customerDao} el-expression (line 18) will be resolved by Spring framework, costomerDao is defined in Spring application-context.xml file.

1.4 -Create managed bean

JSF application uses a bean with each page in the application. The bean defines the properties and methods associated with the UI components used on the page. A bean can also define a set of methods that perform functions, such as validating the component’s data, for the component. The model object bean is like any other JavaBeans component: it has a set of accessor methods. The source code below present a managed bean used in this application example to add a customer.

import java.util.List;
import com.mycompany.dao.ICustomerDao;
import com.mycompany.entity.Customer;
import com.mycompany.entity.CustomerOrder;

/**
 * @author abdelkafi samer
 */
public class CustomerController {
private ICustomerDao customerDao;
private String customerId;
private String taxId;
private String name;
private String adresse;
.............
.....
private List<CustomerOrder> customerOrders;
private List<Customer> customers;
    
public void save(){
    	Customer customer= new Customer(Integer.parseInt(taxId), name, adresse, city, state, zip, phone, null);
    	customerDao.save(customer);
}

public ICustomerDao getCustomerDao() {
	return customerDao;
}


// getters and setters
................
.......
}

1.5 – Create facelets files

Using facelets template increase re-use and simplify maintenance on your JavaServer Faces project. The picture bellow prent the template used in this application example. To browse the source code click on the file name of the page.

template.xhtml

header.xhtml
menu.xhtml
customerEdit.xhtml

The picture below presents the basic JSF screen of the application.

2 – Add RichFaces Support to the application

In this part, I present a way to enhance JSF application user interface by using RichFaces library.

2.1 – Add richfaces dependencies

In the pom.xml file we need to add RichFaces dependencies as shown in the source code bellow.

<dependencies>
	...........
	<dependency>
		<groupId>org.richfaces.ui</groupId>
		<artifactId>richfaces-ui</artifactId>
		<version>3.3.3.Final</version>
	</dependency>

	<dependency>
		<groupId>org.richfaces.framework</groupId>
		<artifactId>richfaces-api</artifactId>
		<version>3.3.3.Final</version>
	</dependency>

	<dependency>
		<groupId>org.richfaces.framework</groupId>
		<artifactId>richfaces-impl</artifactId>
		<version>3.3.3.Final</version>
	</dependency>
		<dependency>
		<groupId>com.uwyn</groupId>
		<artifactId>jhighlight</artifactId>
		<version>1.0</version>
	</dependency>
	..........
</dependencies>

2.2 – Add reachfaces pram and filter to web.xml file

RichFaces need some parameters (SKIN, VIEW_HANDLERS, LoadScriptStrategy …) to be specified in web.xml file.


	<context-param>
		<param-name>org.richfaces.SKIN</param-name>
		<param-value>blueSky</param-value>
	</context-param>
	
	<context-param>
		<param-name>org.ajax4jsf.VIEW_HANDLERS</param-name>
		<param-value>com.sun.facelets.FaceletViewHandler</param-value>
	</context-param>

	<context-param>
		<param-name>org.richfaces.LoadScriptStrategy</param-name>
		<param-value>ALL</param-value>
	</context-param>
	
	<context-param>
	    <param-name>org.richfaces.LoadStyleStrategy</param-name>
	    <param-value>ALL</param-value>
	</context-param>
	
	<filter>
		<display-name>RichFaces Filter</display-name>
		<filter-name>richfaces</filter-name>
		<filter-class>org.ajax4jsf.Filter</filter-class>
	</filter>
	<filter-mapping>
		<filter-name>richfaces</filter-name>
		<servlet-name>Faces Servlet</servlet-name>
		<dispatcher>REQUEST</dispatcher>
		<dispatcher>FORWARD</dispatcher>
		<dispatcher>INCLUDE</dispatcher>
	</filter-mapping>


2.3 – Modify Facelets files

RichFaces has many components, you can explore them from this link.

To use Richfaces component we need to add xmlns (xml namespaces) to the facelets file and replace basic JSF tag by rich faces one.

<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml"
	xmlns:ui="http://java.sun.com/jsf/facelets"
	xmlns:f="http://java.sun.com/jsf/core"
	xmlns:h="http://java.sun.com/jsf/html"
	xmlns:a4j="http://richfaces.org/a4j"
	xmlns:rich="http://richfaces.org/rich">

<ui:composition template="./template/template.xhtml">
  
<ui:define name="body">
 
<f:view >

	<a4j:form>
		<rich:panel>
        <f:facet name="header">
        	<h:outputText value="Edit Customer"/>
        </f:facet>
        <h:panelGrid columns="3" title="Customer" rowClasses="s1row" columnClasses="wfcol1,wfcol2,wfcol3">
        <h:outputText value="Name: " />
			<h:inputText value="#{customer.name}" id="name" required="true"/>
			<rich:message for="name" />
			
			<h:outputText value="Phone: " />
			<h:inputText value="#{customer.phone}" id="phone" required="true"/>
			<rich:message for="phone" />
			
			<h:outputText value="Address: " />
			<h:inputText value="#{customer.adresse}" id="adresse" required="true"/>
			<rich:message for="adresse" />
			
			<h:outputText value="TaxId: " />
			<h:inputText value="#{customer.taxId}" id="taxId" required="true">
				<f:validateLongRange minimum="0" maximum="100"/>
			</h:inputText>
			<rich:message for="taxId" />
			
			<h:outputText value="City: " />
			<h:inputText value="#{customer.city}" id="city" required="true"/>
			<rich:message for="city" />
			
			<h:outputText value="State: " />
			<h:inputText value="#{customer.state}" id="state" required="true"/>
			<rich:message for="state" />
			
			<h:outputText value="Zip: " />
			<h:inputText value="#{customer.zip}" id="zip" required="true">
				<f:validateLongRange minimum="0" maximum="9999"/>
			</h:inputText>
			<rich:message for="zip" />
			
			<f:facet name="footer"> 
				<a4j:commandButton action="#{customer.save}"  value="save"/>
			</f:facet>
			</h:panelGrid>
    	</rich:panel>
				
	</a4j:form>
	
</f:view>

</ui:define>	
</ui:composition>

</html>

This picture presents an application screen after Richfaces integration. This screen uses Ajax to communicate with the server. The save button doesn’t reload the whole page, it just call the save method in the managed bean and update the screen.

DbUnit – Test and populate database with DbUnit, Hibernate and Spring

In enterprise Java applications development we need to test applications with unit tests. Usually, running a test one time can change database data. This can block running the test a second time because of integrity constraints. There are many solutions to solve this problem like:

  • Running SQL script.
  • Restoring a database.
  • Creating and populating a database with test data.
   

Photo credit: Marta

I think there isn’t a better solution, but some of them are more appropriate for some kind of projects.

Creating a script for initializing database is good solution for project using a big database and which need a large range of data to run significant test, because creating or restoring a database can take a lot of time and machine resources. But it can be complicated to create the script because we need to respect data dependency and to have someone in a team who has good SQL knowledge.

Restoring a data base is a good solution for a project with a stable database schema. A frequent database changes costs a lot of time. At every change, we need to restore a database, to make changes and to create a new backup before running application tests

Creating and populating a database is used for testing applications with small database and for new application developments (Development from scratch). This can be done by creating SQL scripts and running them before executing tests. There is more elegant solution to create and populate database which are based on an ORM like Hibernate and a database testing framework like DbUnit.

DbUnit is a JUnit extension (also usable with Ant) targeted at database-driven projects that, among other things, puts your database into a known state between test runs. This is an excellent way to avoid the myriad of problems that can occur when one test case corrupts the database and causes subsequent tests to fail or exacerbate the damage. [DbUnit web site]

In this post I will present one way of creating, populating and testing a Java application by using Hibernate JPA, Spring and DbUnit.

1 – Creating a Hibernate JPA Project with Spring

In this article I use the same project created in the article Using Hibernate JPA in Spring. You can browse the project in this link or you can checkout the project code from Google code SVN repository from this URL https://project4example1.googlecode.com/svn/trunk. After you check out the project into your IDE, the project will be structured as shown in the picture.

To add DbUnit in your project, you need to add “dbUnit.jar” to the project library. If you are using Maven you need to add DbUnit dependency in your pom.xml as shown in the code source bellow.

<dependency>
	<groupId>org.dbunit</groupId>
	<artifactId>dbunit</artifactId>
	<version>2.4.7</version>
	<scope>test</scope>
</dependency>
   

2 – Populate the database with DbUnit

The code source bellow presents the content of the FlatXmlDataSet.xml used in this project. The structure of the file is easy to understand; Each XML element corresponds to a table row. Each XML element name corresponds to a table name. The XML attributes correspond to table columns.

<!DOCTYPE dataset SYSTEM "src/test/resources/my-dataset.dtd">
<dataset>
	<customer customer_id="1" tax_id="2" name="name1" adresse="adresse1"
		city="Paris" state="Paris" zip="75001" phone="0606060606" />
	<customer customer_id="2" tax_id="3" name="name2" adresse="adresse2"
		city="Paris" state="Paris" zip="75002" phone="0606060607" />
	<customer customer_id="3" tax_id="4" name="name3" adresse="adresse3"
		city="Paris" state="Paris" zip="75003" phone="0606060608" />

	<customer_order order_id="1" customer_id="1"
		date_placed="2008-01-01" date_promised="2008-02-02" terms="terms"
		status="done" />
	<customer_order order_id="2" customer_id="2"
		date_placed="2009-02-02" date_promised="2009-04-20" terms="terms"
		status="done" />
	<customer_order order_id="3" customer_id="2"
		date_placed="2010-03-03" date_promised="2010-05-24" terms="terms"
		status="done" />
	<customer_order order_id="4" customer_id="3"
		date_placed="2008-04-04" date_promised="2008-07-05" terms="terms"
		status="done" />
</dataset>

To control data format you can add DTD file. This file is optional if you don’t want to use a DTD file you have to replace the first line of your flat XML dataset by <?xml version='1.0' encoding='UTF-8'?>.

<!ELEMENT dataset (
    customer*,
    customer_order*)>

<!ELEMENT customer EMPTY>
<!ATTLIST customer
	customer_id  CDATA #REQUIRED
	tax_id  CDATA #REQUIRED
	name  CDATA #REQUIRED
	adresse  CDATA #REQUIRED
	city  CDATA #REQUIRED
	state  CDATA #REQUIRED
	zip  CDATA #REQUIRED
	phone  CDATA #REQUIRED   
>

<!ELEMENT customer_order EMPTY>
<!ATTLIST customer_order
	order_id CDATA #REQUIRED
	customer_id CDATA #REQUIRED
	date_placed CDATA #REQUIRED
	date_promised CDATA #REQUIRED
	terms CDATA #REQUIRED
	status CDATA #REQUIRED
>

The code source bellow presents a jUnit test used to test a DAO. Before test execution, the database will be created by Hibernate and it will be populated by DbUnit with XML dataset. In the “setup” method CLEAN_INSERT operation is executed; it deletes all rows in tables and insert data from the data set.

package com.mycompany.test.dao;

import java.io.InputStream;
import java.sql.Connection;
import java.util.Collection;

import junit.framework.TestCase;

import org.dbunit.database.DatabaseConnection;
import org.dbunit.database.IDatabaseConnection;
import org.dbunit.dataset.IDataSet;
import org.dbunit.dataset.xml.FlatXmlDataSet;
import org.dbunit.operation.DatabaseOperation;
import org.hibernate.SessionFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.orm.hibernate3.SessionFactoryUtils;

import com.mycompany.dao.ICustomerDao;
import com.mycompany.entity.Customer;

public class CustomerDaoTest extends TestCase {

	private static final String[] LOCATIONS = { "application-context.xml" };
	private static final String FLAT_XML_DATASET = "FlatXmlDataSet.xml";
	private ApplicationContext context;
	private ICustomerDao iCustomerDao;


	@Override
	protected void setUp() throws Exception {
		super.setUp();
		context = new ClassPathXmlApplicationContext(LOCATIONS);
		iCustomerDao = (ICustomerDao) context.getBean("customerDao");
		DatabaseOperation.CLEAN_INSERT.execute(getConnection(), getDataSet());

	}

	public void testGetAllCustomers() {
		Collection<Customer> listCustomers = iCustomerDao.getAll();
		assertFalse(listCustomers.isEmpty());
	}
	
	public void testSaveCustomer() {
		Collection<Customer> listCustomers1 = iCustomerDao.getAll();
		Customer customer = new Customer(1, "name","adresse", "city", "state", "123", "0606060606", null);
		iCustomerDao.save(customer);
		Collection<Customer> listCustomers2 = iCustomerDao.getAll();
		assertEquals(listCustomers2.size() - listCustomers1.size(), 1);
	}
	

	private IDataSet getDataSet() throws Exception {
		InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream(FLAT_XML_DATASET);
		IDataSet dataset = new FlatXmlDataSet(inputStream);
		return dataset;
	}

	private IDatabaseConnection getConnection() throws Exception {
		SessionFactory sessionFactory = (SessionFactory) context.getBean("sessionFactory");
		Connection jdbcConnection = SessionFactoryUtils.getDataSource(sessionFactory).getConnection();
		IDatabaseConnection connection = new DatabaseConnection(jdbcConnection);
		return connection;
	}
}


To test java applications we need to know data at initial state to predict data evolution and to make JUnit assertion. DbUnit gives a smart solution to populate a database. DbUnit is dedicated for applications tests, but I think it could be useful in others contexts like application deployment when we need to fill reference data.

Using Hibernate JPA in Spring

JPA (Java Persistence API) provides a good ORM (Objet Relational Mapper) solution. It has a large success because it’sa standard and it’s implemented by different vendor.

Hibernate Implements JPA specification. Using this implementation has the benefit of avoiding hbm.xml mapping files and to use annotations metatdata to specify the mapping between objects and relational database tables.

This article will show by a project example how to persist data with Hibernate JPA implementation and Spring Framework.

   
Photo Credit : tanakawho

The picture bellow presents the project structure and the different files created. If you are using maven you need to add dependency as shown in the picture, otherwise you have to download jars from Springsource and Hibernate web sites and to manage dependencies.

   

1 – Hibernate JPA configuration
The JPA interface needs a configuration file named persistence.xml in the application’s META-INF directory. The sourcecode bellow present the persistence.xml file used in this project.

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="1.0" 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">
    <persistence-unit name="acme" transaction-type="RESOURCE_LOCAL">
        <provider>org.hibernate.ejb.HibernatePersistence</provider>
        <class>com.mycompany.entity.CustomerOrder</class>
        <class>com.mycompany.entity.Customer</class>
        <properties>
            <property name="hibernate.hbm2ddl.auto" value="create-drop"/>
        </properties>
    </persistence-unit>
</persistence>

JPA persist a simple POJO Classe with some metatdata wich are specified in annotations. For more information about JPA annottion, see Chapter 8 “Metadata Annotations” of the JPA Specification . Here is an example data class:

import java.io.Serializable;
import java.util.List;
import javax.persistence.*;
import org.hibernate.annotations.GenericGenerator;

@Entity
@Table(name = "Customer")
public class Customer implements Serializable {

    public Customer() {super();}

public Customer(Integer taxId, String name, String adresse, String city, 
String state, String zip, String phone, List<CustomerOrder> CustomerOrders) {
        this.taxId = taxId;
        this.name = name;
        this.adresse = adresse;
        this.city = city;
        this.state = state;
        this.zip = zip;
        this.phone = phone;
        this.CustomerOrders = CustomerOrders;
    }

    @Id
    @GenericGenerator(name = "generator", strategy = "increment")
    @GeneratedValue(generator = "generator")
    @Column(name = "customer_id", nullable = false)
    private Long customerId;

    @Column(name = "tax_id", nullable = false)
    private Integer taxId;

    @Column(name = "name", nullable = false)
    private String name;

    @Column(name = "adresse", nullable = false)
    private String adresse;

    @Column(name = "city", nullable = false)
    private String city;

    @Column(name = "state", nullable = false)
    private String state;

    @Column(name = "zip", nullable = false)
    private String zip;

    @Column(name = "phone", nullable = false)
    private String phone;

    @OneToMany
    private List<CustomerOrder> CustomerOrders;

    // Add getters and setters
}

2 – Using JPA in Spring
In this part we explain how to integrate Hibernate JPA implementation into Spring.
The source code bellow present the application context used to configure Hibernate JPA into Spring Framework.

<?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:aop="http://www.springframework.org/schema/aop"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:flow="http://www.springframework.org/schema/webflow-config"
       xmlns:lang="http://www.springframework.org/schema/lang"
       xmlns:osgi="http://www.springframework.org/schema/osgi"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xmlns:util="http://www.springframework.org/schema/util"
       xmlns:p="http://www.springframework.org/schema/p"

       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
          http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
          http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
          http://www.springframework.org/schema/webflow-config http://www.springframework.org/schema/webflow-config/spring-webflow-config-2.0.xsd
          http://www.springframework.org/schema/lang http://www.springframework.org/schema/lang/spring-lang-3.0.xsd
          http://www.springframework.org/schema/osgi http://www.springframework.org/schema/osgi/spring-osgi-3.0.xsd
          http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
          http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.0.xsd
">
    
	<context:annotation-config/>
    <context:component-scan base-package="com.mycompany"/>
    

    <bean id="entityManagerFactory"
     class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
        <property name="dataSource" ref="dataSource" />
        <property name="persistenceXmlLocation" value="persistence.xml"  />
        <property name="jpaVendorAdapter">
            <bean
        class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
                <property name="showSql" value="true" />
                <property name="generateDdl" value="true" />
                <property name="databasePlatform" value="org.hibernate.dialect.HSQLDialect" />
            </bean>
        </property>
    </bean>

    <bean id="dataSource"
     class="org.apache.commons.dbcp.BasicDataSource"
     destroy-method="close">
        <property name="driverClassName" value="org.hsqldb.jdbcDriver" />
        <property name="url" value="jdbc:hsqldb:mem:test" />
        <property name="username" value="sa" />
        <property name="password" value="" />
    </bean>

	<tx:annotation-driven />
    <bean id="transactionManager"
     class="org.springframework.orm.jpa.JpaTransactionManager" >
        <property name="entityManagerFactory" ref="entityManagerFactory"  />
    </bean>
      

</beans>

The code source bellow present the customer DAO.

package com.mycompany.dao.hibernate;

import java.util.Collection;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;
import com.mycompany.dao.ICustomerDao;
import com.mycompany.entity.Customer;

@Repository
public class CustomerDao implements ICustomerDao{
	
	@PersistenceContext
	private EntityManager em;

    public Collection<Customer> getAll() {
    	Query query = em.createQuery("from Customer");
        return query.getResultList();
    }
    
    public Collection<Customer> findByName(String name) {
    	Query query = em.createQuery("from Customer as c where c.name like :name");
    	query.setParameter("name", name);
        return query.getResultList();
    }

    public Customer getById(Long id) {
        return em.find(Customer.class, id);
    }

    @Transactional
    public void save(Customer customer) {
        em.persist(customer);
    }

    @Transactional
    public void delete(Long id) {
    	Customer customer = em.find(Customer.class, id);  
    	em.remove(customer);
    }
}