Saturday, July 11, 2020

Data Access in Spring Framework

This Spring data access tutorial provides basics about the DB access through Spring framework like how Spring abstracts the data access, how you can use templates for data access, Spring’s data access exception handling.

If you have to describe how data access is handled by Spring Framework using 2 keywords then those 2 words will be-

  • Abstraction
  • Agnostic

Now JDBC or any ORM framework do provide abstraction of its own and you use JDBC or ORM as an abstract layer to interact with DB then what abstraction does spring provide?

Again two keywords are-

  • Template
  • Exception Handling

Before delving any further into those keywords let’s talk about the “agnostic” feature too (which will cover the Exception handling point too!). It is said that data access exception handling in Spring framework is platform agnostic. What does that mean?

Spring’s data access exception handling is platform agnostic

If you have used JDBC you must be knowing that it forces you to catch SQLException. SQLException is an exception that provides information on a database access error or other errors some of the scenarios when SQLException can be thrown are-

  • The application is not able to connect to the DB.
  • SQL Query which has to be executed is not correct syntactically.

But the question here is by catching SQLException you can’t do much anyway. Also the SQLException hierarchy is not very rich. Though it does provide a String describing the error and an integer error code that is specific to each vendor which is helpful in knowing about the error.

Coming to Spring framework it provides data access mechanism for getting data through JDBC, various ORM frameworks like Hibernate, Ibatis. Now think of a situation where Spring provides the layer over the JDBC or any ORM framework but doesn’t provide any mechanism to handle exceptions thrown by them. In that case your code will become a hotchpotch of Spring templates and then exception handling by JDBC, Hibernate, Ibatis or any other way of data access. That’s where Spring’s platform agnostic exception handling comes to the rescue.

For JDBC org.springframework.jdbc.support package provides SQLException translation functionality and some utility classes. Exceptions thrown during JDBC processing are translated to exceptions defined in the org.springframework.dao package. This means that code using the Spring JDBC abstraction layer does not need to implement JDBC or RDBMS-specific error handling.

All translated exceptions are unchecked exceptions, which gives you the option of catching the exceptions from which you can recover while allowing other exceptions to be propagated to the caller.

Same way implementations of PersistenceExceptionTranslator interface in Spring provides exception translation for data access technologies that throw runtime exceptions, such as JPA, TopLink, JDO and Hibernate.

Using these translator classes Spring translates the platform specific exception to the Spring specific exception under the hood, so you are abstracted from how it is done.

Some of the advantages of the exception handling mechanism followed by Spring are-

  1. Non-intrusive– Since data access exceptions thrown by Spring are not checked exceptions so user is not forced to handle it or declare it. That way you are not making your application tightly coupled with the Spring APIs.
  2. Catch Late- In case of checked exceptions, it is enforced by Java compiler to either catch the exception or declare it in throws clause. So generally developer tends to catch it and do nothing except printing stacktrace or put a logger in order to avoid the compiler error. But that way we are not providing the true information of what exactly happened. It is better to catch exception only when it can be handled appropriately. Since Spring's data access exceptions are unchecked exceptions theses exceptions can be thrown up the call hierarchy, without the botheration of declaring with throws clause or rethrowing them, and the best place in the hierarchy can handle it more effectively.

Spring data access Exception Hierarchy

Spring’s exception hierarchy is quite rich and the main thing is that it can be used with any persistence solution. Whatever persistence solution you are using, if exception is thrown Spring framework will translate it and throw a consistent set of exceptions.

Parent class in Spring's exception hierarchy is DataAccessException and important point about is that it is an unchecked exception. So, you are not forced to catch Spring's data access exceptions, though you can catch them if you want. In fact the convention is that you should not handle any exceptions in the DAO layer, instead throw it to the front-end and handle it.

Some of the sub classes of the DataAccessException class are– BadSqlGrammarException, DuplicateKeyException, EmptyResultDataAccessException, CannotGetJdbcConnectionException, QueryTimeoutException. There are many more if you want to go through the whole list please refer Spring reference doc.

In order to take advantage of Spring’s data-access exceptions, you need to use one of the data access templates provided by Spring framework. That brings us to the point about templates.

Using Templates for Data Access in Spring

Spring provides many templates for data access (For JDBC, for Hibernate, for MongoDB and many more). If you have idea about template design pattern you can get an idea what these templates are doing.

You generally use Template design pattern if you have to design the functionality where some implementation is common among the classes and some implementation differs. So in template design pattern -

  • There is a base class with common implementations.
  • Methods that require individual implementation are mere place holder in base class.
  • Sub classes can provide implementation for those place holder methods.

So, base class provides the template of the implementation and fill what it can (common implementation) and delegates the other parts to the implementing classes.

Same process is used by the Spring data access. Whatever persistence mechanism is used there are some common steps like getting the DB connection, handling exception if thrown and cleaning up the resources (closing the connection) once done. These can be termed as fixed part.

But how and what data is accessed, what data is updated is different for different application. That can be termed as variable part.

Template classes in Spring framework provide implementation for the fixed part and uses a callback approach to handle variable part which is your custom data access code, benefit of template class is that it frees application code from having to do the boilerplate tasks like getting DB connection, handling exceptions, closing connection and results in code that is intention driven. That way the code that is written focuses solely on what the developer wants to do.

As example- JdbcTemplate class is the central class in the JDBC core package. It handles the creation and release of resources, which helps you avoid common errors such as forgetting to close the connection.
It performs the basic tasks of the core JDBC workflow such as statement creation and execution, leaving application code to provide SQL and extract results. The JdbcTemplate class executes SQL queries, update statements and stored procedure calls, performs iteration over ResultSets and extraction of returned parameter values. It also catches JDBC exceptions and translates them to the generic, more informative, exception hierarchy defined in the org.springframework.dao package.

When you use the JdbcTemplate for your code, you only need to implement callback interfaces, giving them a clearly defined contract. The PreparedStatementCreator callback interface creates a prepared statement given a Connection provided by this class, providing SQL and any necessary parameters. The same is true for the CallableStatementCreator interface, which creates callable statements. The RowCallbackHandler interface extracts values from each row of a ResultSet.

Some of the templates provided by Spring framework-

  • jdbc.core.JdbcTemplate– For JDBC connections.
  • jdbc.core.namedparam.NamedParameterJdbcTemplate- For JDBC connections with named parameters.
  • orm.hibernate3.HibernateTemplate– For Hibernate 3.x sessions.
  • orm.hibernate4.HibernateTemplate- For Hibernate 4.x sessions.
  • org.springframework.orm.hibernate5.HibernateTemplate- For Hibernate 5.x sessions.

In order to manage the fixed part like getting connection, releasing resources Spring template needs a reference to a DataSource. Refer Configuring DataSource in Spring Framework to see different ways to configure data source in Spring.

That's all for this topic Data Access in Spring Framework. If you have any doubt or any suggestions to make please drop a comment. Thanks!

>>>Return to Spring Tutorial Page


Related Topics

  1. Spring NamedParameterJdbcTemplate Insert, Update And Delete Example
  2. Spring JdbcTemplate With ResultSetExtractor Example
  3. Spring Batch Processing Using JDBCTemplate batchUpdate() Method
  4. How to Inject Prototype Scoped Bean in Singleton Bean
  5. How to Read Properties File in Spring Framework

You may also like-

  1. Dependency Injection in Spring Framework
  2. Autowiring using XML configuration in Spring
  3. Lazy Initialization in Spring Using lazy-init And @Lazy Annotation
  4. Creating a Maven project in Eclipse
  5. Lambda expressions in Java 8
  6. LinkedHashMap in Java With Examples
  7. Difference Between ReentrantLock and Synchronized in Java
  8. Switch Case Statement in Java With Examples