'Spring'ing the new app
What to expect from this post?
Building something new, something from scratch, something worth is an opportunity most yearn for, if not all. I feel blessed and lucky to have had opportunities of developing not one but a few of such projects. And yet again, I have an opportunity - a bigger one, a better one, a bit more challenging one.. to build a product .... to architect, design, develop the product and take it to the cloud!
This post intends to provide insights into 'Spring'ing this new app - how our team is approaching building this product, using 'Spring'.
Spring - 'Soul' of the app
Choosing the framework for a J2EE application is really not difficult these days. Spring is such comprehensive a framework, that more often than not, it is the obvious selection as a framework for a J2EE application. What made Spring work for us, besides being a solid, high quality implementation, is the wide availability of features that expedite the development process such as:
- support for restful web services
- spring-hibernate integration
- support for transaction management
- spring-jdbc integration
- spring-quartz integration
- support for asynchronous execution
- support for cross-cutting concerns, through aspect-oriented-programming
- support for exception handling
- support for validations, conversions and custom annotations
- support for unit testing
- support for authentication, through spring-security
.... continued .... the list is big.
REST and Hibernate : hand-in-hand development
The first steps to building an app are setting up the infrastucture - building the controller and integration layers. We chose REST and Hibernate, respectively, as the foundation for our app.
REST-ifying the App
The motivation to go the 'RESTful' way strong considering the inclination to architect our application as microservices. The Spring MVC's support for RESTful Web services and it's easy integration with JSP's or the javascript MVC/MVVM frameworks made Spring MVC a perfect fit for our app. Spring's message converters added the cherry to the cake - simply use libraries like Jackson, JAX-B, XStream, etc and we are done.
Hibernate-ing the App
After evaluating few NoSQL and RDBMS databases, we had zeroed down on Oracle, simply because it fitted our use-case, oracle is considered the best and team was already working on oracle. While there was a direction to go the simple JDBC route since we do not need the 'database-agnostic' feature of hibernate, we went against the direction and implemented hibernate as the database integration layer - to account for the uncertainties in the world of software development. This decision also meant we embrace the learning curve involved for hibernate and we did put our best foot forward.
Guess what, the situation changed, we had not other option and circumstances demanded we move to 'MySQL' from 'Oracle'. The team's decision to implement hibernate, as the data integration layer, paid off since we needed just a week to migrate our app from Oracle to MySQL. If you have a question 'Why did we need a week to migrate from Oracle to MySQL, if we were using Hibernate', I will address it in another blog post later.
Transaction Management, and integrating JDBC
JDBC Integration
While we used hibernate as our data integration layer API, we also needed JDBC integration for our 10% use cases of batch inserts and updates. Spring proved to be great supporting both integration APIs with its consistent programming model.
Transaction Management
Spring has comprehensive support for transaction management - declarative as well as programmatic, for different transaction APIs like JTA, JDBC, Hibernate, JPA and JDO.
We adopted the declarative approach, annotation-based with no or little programming required, which is also the recommended approach.
We have two transaction managers, one for hibernate and one for JDBC, working in conjunction with each other.
Other aspects considered in transaction management were 'transaction boundaries', 'read-only' transactions and 'propagation type'.
- Major decision around 'transaction boundaries' was to introduce the facade controller and place the 'transaction boundary' of the transaction over this facade controller.
- The getter APIs are marked 'read-only' so that hibernate optimizes around dirty-checks and manual flush.
- Two types of propagation type were used - 'PROPAGATION_REQUIRED' and 'PROPAGATION_REQUIRES_NEW' - as both use cases were required to be supported.
Centralized Exception handling
One of the good practices of REST APIs is to respond with correct exception details:
- HTTP Status code
- Error Code
- Error Message
Spring provides perfect support to achieve this RESTification practice. With '@ControllerAdvice' annotation, the centralized exception handling can be setup to handle different exceptions and respond correctly with the exception details.
To be continued..
Spring-Quartz integration
Asynchronous execution
Cross-cutting concerns, through aspect-oriented-programming
Support for validations, conversions and custom annotations
Support for unit testing
Support for authentication, through spring-security
... to add more features as encountered and utilized.