October 25, 2014
Hot Topics:
RSS RSS feed Download our iPhone app

Data Support in Spring Framework

  • February 11, 2013
  • By Manoj Debnath
  • Send Email »
  • More Articles »

Introduction

Data support for an enterprise framework is non-trivial because most applications ultimately persist business information in a database. Without any native support Spring acts as a catalyst in providing a fertile ground for implementing a variety of data access technology rather than taking part in the process itself. Spring data access is slightly different than that of its other features in that core Spring AOP (Aspect Oriented Programming) or DI (Dependency Injection) is more of a generic or an open ended property. One can use it for Spring data support or in a totally different area of programming. But when we speak of data support it is specifically for the purpose of your application interacting with data or a database only.

Spring Data Access

While interacting with a database there are a few things we have to do irrespective of the business logic we are writing, such as – open connection, close connection, manage transaction. This often requires writing a lot of repetitive and cumbersome boilerplate code. With Spring data support we can do away with all of the repetitive task and focus specifically on the business problem we are trying to solve. In Java there are numerous ways to interact with the database, be it an Object Relational Mapping (ORM) tool like JPA (Java Persistence API), JDO (Java Data Objects) or Hibernate; lightweight frameworks like iBATIS or Spring JDBC support; or NoSQL solution like MongoDB, Redis, Neo4J. Spring supports many of these technologies and provides an appropriate environment to assimilate, explore and choose the best possible option to develop sophisticated business services and data access objects. Due to this variety, application builds in Spring are robust and scalable with a provision of a spectrum of data access technology blending under the same hood.

Exception Hierarchy

Spring provides a consistent data access exception hierarchy with the class DataAccessException as its root. Technology-specific exceptions such as Hibernate, JDO, or JPA are wrapped within Spring's data access exception handling domain.

Data Access Exception Hierarchy

Data Access Exception Hierarchy

This provides a more focused persistence exception handling mechanism. Without annoying boilerplate code of catch-and-throw block declaration in one's DAO, developers can handle exceptions in appropriate layers within the consistent programming model.

Annotation Based Configuration

Any POJO (Plain old Java Object) can be configured to Spring data access objects with the use of @Repository annotation. This annotation triggers component scanning and repository configuring within the class definition rather than using XML configuration entries.

@Repository


public class CustomerDAOImpl extends CustomerDAO{

       //...

}

DAO requires access to a persistent resource and there are different technology based repositories such as JDBC, JDO, JPA, and Hibernate to name a few. Configuring any of them is pretty straightforward and simple, with an injection of resource dependency through @Autowired, @Inject, @Resource, @PersistenceContext.

Configuring JPA repository

@Repository


public class CustomerDAOImpl extends CustomerDAO{

       @PersistenceContext

       private EntityManager entityManager;

       //...        

}

 

Inject SessionFactory in case of Hibernate

@Repository


public class CustomerDAOImpl extends CustomerDAO{

       private SessionFactory sessionFactory;

       @Autowired

       public void setSessionFactory(SessionFactory sessionFactory){

             this.sessionFactory = sessionFactory;

       }

       //...  

}

In case of using JdbcTemplate

@Repository

public class CustomerDAOImpl extends CustomerDAO{

       private JdbcTemplate template;

       @Autowired

       public void setTemplate(DataSource dataSource){

             this.template = new JdbcTemplate(dataSource);

       }

       //...  

}

 

DataSource: Database Connection Management

DataSource is the generic connection factory according to JDBC specification, through which Spring obtains connection to the database. Connection pooling and transaction management is done with the help of DataSource. When connecting with the database one has to either obtain data source from JNDI or configure one's own connection pool. As Spring has no native support while configuring a connection pool, one has to rely on third party vendors to provide the connection pooling API. Popular implementations of the genre are Apache Jakarta Commons DBCP and C3P0. However, note that the use of DriverManagerDataSource as the data source is optional or should be used only for testing purposes. Since this class is not tailored to handle multiple requests or pooling, it will have a diminished performance on multiple connection requests. Connection with DriverManagerDataSource can be established both through XML or through Java code.

Through Java code

...


DriverManagerDataSource dataSource = new DriverManagerDataSource();

dataSource.setDriverClassName("com.mysql.jdbc.driver");

dataSource.setUrl("jdbc:mysql://localhost:3306/db");

dataSource.setUsername("root");

dataSource.setPassword("admin");

...

Through XML configuration

...
<bean id="dataSource"

       class="org.springframework.jdbc.datasource.DriverManagerDataSource">

       <property name="driverClassName" value="com.mysql.jdbc.Driver" />

       <property name="url" value="jdbc:mysql://localhost:3306/db" />

       <property name="username" value="root" />

       <property name="password" value="admin" />

</bean>
...
 

Spring JDBC Framework

Spring basically provides three types of template for JDBC data access:

JdbcTemplate: A basic thread-safe class to handle database access. The class JdbcDaoSupport of Spring JDBC framework simplifies DAO implementation. The jdbcTemplate property of this class can be used from IoC (Inversion of Control aka. Dependency Injection) container to create JdbcTemplate from the data source.

public class CustomerDaoImpl implements CustomerDao {    

      private JdbcTemplate jdbcTemplate;

       public void setDataSource(DataSource dataSource){

             jdbcTemplate = new JdbcTemplate(dataSource);

       }

             

      public void insert(final Customer customer){

             String sql = "INSERT INTO CUSTOMER VALUES(?,?,?)";

             jdbcTemplate.update(sql,new Object[]{customer.getId(),                          customer.getName(), customer.getAddress()});

       }

//...

}

 

NamedParameterJdbcTemplate: This JdbcTemplate wrapper class provides the name value pair for conventional JDBC placeholders.

public class CustomerDaoImpl implements CustomerDao {    

       private NamedParameterJdbcTemplate nParamJdbcTemplate;

 

       public void setDataSource(DataSource dataSource){

             nParamJdbcTemplate = new NamedParameterJdbcTemplate(dataSource);

       }

                    

       public int countCustomerByName(String name){

             String sql = "SELECT COUNT(*) FROM CUSTOMER WHERE name = :name";

             SqlParameterSource paramMap =  new MapSqlParameterSource("name", name);

             return nParamJdbcTemplate.queryForInt(sql, paramMap);

       }

//...

}

SimpleJdbcTemplate: This is also a wrapper class of JdbcTemplate and uses the Java 5 language features of varargs and autoboxing. However, since Spring 3.1 it is deprecated. JdbcTemplate and NamedParameterJdbcTemplate now provide all the functionality of the SimpleJdbcTemplate.

JDBC Extension

The Spring JDBC extension is built on top of the spring-jdbc module. It provides advanced JDBC support for Oracle. Apart from supporting common JDBC features, the extension includes type-safe QueryDSL queries, which can be used for any SQL supported database. A typical query to database using QueryDslJdbcTemplate is as follows.

private final QCustomer qcust = new QCustomer.customer;

...

QueryDslJdbcTemplate qdjt = new QueryDslJdbcTemplate(dataSource);

...

SqlQuery query = qdjt.newSqlQuery().from(qcust).where(qcust.ssn.eq(ssn));

...

 

Spring ORM Data Access

Spring provides a very convenient way to integrate popular object relational persistence frameworks such as Hibernate, JPA, JDO and iBATIS for data access object, transaction and resource management implementation. Apart from configuring all the OR (Object Relational) mapping tools supported features through Dependency Injection, they can comply with Spring's generic transaction features and DAO exception hierarchies. Spring does not impose a particular methodology; rather it acts as generic socket where developers can plug in any ORM framework, or even combine them according to the choice and convenience.

Hibernate

The  configuration of Hibernate in Spring can be used to define resources such as JDBC DataSource or Hibernate SessionFactory as Spring container beans. The configuration can be established through annotation or through XML. Below are code excerpts of an XML based configuration of SessionFactory objects with DBCP data source.

       <bean id="dataSource"

             class="org.apache.commons.dbcp.BasicDataSource">

             <property name="driverClassName" value="com.mysql.jdbc.Driver" />

             <property name="url" value="jdbc:mysql://localhost:3306/db" />

             <property name="username" value="root" />

             <property name="password" value="admin" />

       </bean>

<bean id="sessionFactory"

             class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">

             <property name="mydataSource" ref="dataSource" />

             <property name="packagesToScan" value="org.myapp.model"/>                              

             <property name="hibernateProperties">

                    <props>

<prop key="dialect">

       hibernate.dialect=org.hibernate.dialect.MySQLDialect 

</prop>

             </props>

       </property>

</bean>

 

JDO

Classes for JDO integration in Spring reside in the org.springframework.orm.jdo package. JDO PersistenceManagerFactory implementation is a close match to the JavaBeans pattern, similar to the way JDBC DataSource implementation is configured in Spring. Code excerpts of  JDO implementation with open source PersistenceManagerFactory DataNucleus are as follows:

       <bean id="dataSource"

             ...

       </bean>

 

<bean id="persistentManagerFactory" class="org.datanucleus.jdo.JDOPersistenceManagerFactory"

                    destroy-method="close">

                    <property name="connectionFactory" ref="dataSource" />

                    <property name="nontransactionalRead" value="true" />

             </bean>

 

JPA

Database connection is represented by EntityManager instance, which provides necessary functionality to operate on the database. The EntityManagerFactory is used to instantiate EntityManager for a particular database. There are basically three ways to setup JPA in Spring:

    • Limited JPA Support: For a simple environment you can use LocalEntityManagerFactoryBean, which creates JPA EntityManagerFactory according to its standalone bootstrap contract.  Thus it is suitable for deploying in simple environments, such as stand-alone application and integration testing. This factory bean uses JPA  PersisenceProvider auto detection mechanism and the xml definition to use persistence unit name is quite simple. However, this form of deployment, though simple is very limited because it does not provide support for global transactions as well as no reference can be made to an existing JDBC data source.
<beans>

       <bean id="entityManagerFactory"

       class="org.springframework.orm.jpa.LocalEntityManagerFactoryBean">

             <property name="persistenceUnitName" value="myPU" />

       </bean>

</beans>

JNDI Support

      : Obtaining

EntityManagerFactory

      from JNDI is quite simple. This option is particularly suitable for deploying to a Java EE 5 server. The JNDI location of JDBC data source definition resides in the META-INF/persistence.xml file. The server's JTA integrates

EntityManager's

      transactions and Spring uses dependency Injection to obtain

EntityManagerFactory

      bean by passing it to the application object. The transaction is managed typically through

JtaTransactionManager

      APIs.
<beans>

       <jee:jndi-lookup id="entityManagerFactory" jndi-name="persistence/myPU"/>

</beans>
    • Full JPA Support: Full JPA support can be obtained through LocalContainerEntityManagerFactoryBean. This gives full control over EntityManagerFactory from web containers to stand-alone applications and integration testing.
<beans>

       <bean id="entityManagerFactory"

       class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">

             <property name="dataSource" ref="myDataSource" />

             ...

             </property>

       </bean>

</beans>

 

<persistence xmlns="http://java.sun.com/xml/ns/persistence" version="1.0">

       <persistence-unit name="myPU" transaction-type="RESOURCE_LOCAL">

             <mapping-file>META-INF/applicationContext.xml</mapping-file>

             <exclude-unlisted-classes />

       </persistence-unit>

</persistence>

Spring Data Projects

Apart from conventional DAO support, Spring has:

  • support extension to distributed computing and data storage: Apache Hadoop,
  • support for developing scalable applications using Spring data GemFire as a distributed data management platform,
  • Spring Data REST performing CRUD operations in persistence model using HTTP and Spring Data Repositories,
  • support for key-value store repositories: Redis,
  • support for document-oriented database: MongoDB,
  • distributed column-oriented store: Hbase,
  • shared infrastructure for use across various data access projects: Commons,
  • database unified object mapping framework portable across different databases for Grails: Grails Mapping,
  • transactional database that stores data structured as graphs: Neo4j.

Conclusion

The main objective of Spring Data Access Object support is to make working with the data access technologies such as JDBC, Hibernate, JPA or JDO easy and consistent. Switching between different persistent technologies is simple and fluid. Developers do not have to worry about exception handling, dependency injection and other intricacies specific to each technology by bringing a whole lot of technology under the same hood. This increases the productivity of the developer so they can concentrate solely on the application logic rather than whirling through the vortex of technology configuration management. Plain and simple, Spring tries to provide a complete enterprise solution environment with full support to some popular third party external technologies. The techniques of integration are easy with no-steep learning curve even for the newbie.


Tags: data access, Dependency injection, Spring




Comment and Contribute

 


(Maximum characters: 1200). You have characters left.

 

 


Sitemap | Contact Us

Rocket Fuel