, , , ,

This is part 6 of the tutorial series for building a web application using Spring Boot. In this post we look at adding a DAO Authentication provider for Spring Security.

We started off with the first part by creating our Spring project using the Spring Initializr. In part 2, we rendered a web page using Thymeleaf and Spring MVC. This was followed by part 3 where we looked at setting up Spring Data JPA for database persistence. Part 4 was all about consolidating everything to provide a working Spring Boot MVC Web Application capable of performing CRUD operations.

In the previous part 5 of this series, we configured a basic in-memory authentication provider. It’s a good starting point to learn Spring Security, but as I mentioned there, it’s not for enterprise applications. A production-quality implementation would likely use the DAO authentication provider.

In this part of the series, I will discuss Spring Security with the DAO authentication provider to secure our Spring Boot Web application. We will implement both authentication and role-based authorization with credentials stored in the H2 database. For persistence, we will use the Spring Data JPA implementation of the repository pattern, that I covered in part 3. Although there are several Spring Data JPA implementations, Hibernate is by far the most popular.

As the Spring Data JPA dependency is included in our Maven POM, Hibernate gets pulled in and configured with sensible default properties via Spring Boot.

This post builds upon 5 previous posts. If you’re not familiar with all the content around Spring, I suggest you to go through this series from the start.

JPA Entities

Our application already has a Product JPA entity. We’ll add two more entities, User and Role. Following the SOLID design principle’sprogram to interface ” principle, we will start by writing an interface followed with an abstract class for our entities.

DomainObject.java

AbstractDomainClass.java

The entity classes are as follows.

User.java

Role.java

The User and Role JPA entities are part of the many-to-many relationship. Also, in Line 15 of the User class, notice that the password field is marked as @Transient.

That’s because we don’t want to store the password in text form.

Instead, we will store the encrypted form of the password.

JPA Repositories

Spring Data JPA provides the CRUD Repository feature. Using it, we just define the repository interfaces for our User and Role entities to extend CrudRepository.

The Spring Data JPA repositories for the User and Role entities are as follows.

UserRepository.java

RoleRepository.java

By extending CrudRepository, both the repositories inherit several methods for working with entity persistence, including methods for saving, deleting, and finding entities. Spring Data JPA uses generics and reflection to generate the concrete implementations of both the interfaces.

Spring Data JPA Services

We can now create the services, that will use Spring Data JPA to perform CRUD operations on the User and Role entities.

Of course, we will follow the Interface Segregation principle to maintain loose coupling. It’s always best to “program to interface”, especially when leveraging the benefits of Spring’s dependency injection.

So, let’s start with the service interfaces.

CRUDService.java

UserService.java

RoleService.java

Both RoleService and UserService extends CRUDService that defines the basic CRUD operations on entities. UserService, with the additional findByUsername() method is a more specialized service interface for CRUD operations on User.

We have made the service interfaces generic to mask our service implementations using the Façade design pattern. The implementations can be Spring Data JPA with repository, DAO, or Map patterns, or even plain JDBC, or some external Web service. The client code does not need not to be aware of the implementation. By using interfaces, we are able to leverage multiple concrete implementations of the services.

We’ll write the service implementation classes using the Spring Data JPA repository pattern.

UserServiceImpl.java

In this class, we auto-wired in UserRepository and EncryptionService. Going ahead, we will create EncryptionService using the Jasypt library to add encryption capabilities for storing user passwords. The overridden methods of this class use the UserRepository we created to perform CRUD operations on User.

The RoleServiceImpl provides a similar implementation for RoleService.

RoleServiceImpl.java

Free Spring TutorialPassword Encryption Service

The Jasypt library provides an implementation for unidirectional encryption. We will use Jasypt to encrypt a password before storing it to the database. For authentication, we will provide Jasypt the received password. Under the hood, Jasypt will encrypt the received password and compare it to the stored one.

Let’s add the Jasypt dependency to our Maven POM.

Note: The latest available Jasypt 1.9.2 targets Spring Security 3. But even for Spring Security 4 that we are using, Jasypt doesn’t have compatibility issues.

With Jasypt pulled in, we will write a bean for StrongPasswordEncryptor of Jasypt – a utility class for easily performing high-strength password encryption and checking. The configuration class, CommonBeanConfig is this.

CommonBeanConfig.java

Our generic EncryptionService interface will define two methods to encrypt and compare passwords.

EncryptionService.java

The implementation class is this.

EncryptionServiceImpl.java

In this implementation class, we autowired the StrongPasswordEncryptor bean. In Line 18, the encryptPassword() method encrypts the password passed to it. In Line 22, the checkPassword() method returns a boolean result of the password comparison.

User Details Service Implementation

Spring Security provides a UserDetailsService interface to lookup the username, password and GrantedAuthorities for any given user. This interface provides only one method, loadUserByUsername(). This method returns an implementation of Spring Security’s UserDetails interface that provides core user information.

The UserDetails implementation of our application is this.

UserDetailsImpl.java

In this class, we have defined the fields of our data model and their corresponding setter methods. The SimpleGrantedAuthority we set on Line 16 is a Spring Security implementation of an authority that we will convert from our role. Think of an authority as being a “permission” or a “right” typically expressed as strings.

We need to provide an implementation of the loadUserByUsername() method of UserDetailsService. But the challenge is that the findByUsername() method of our UserService returns a User entity, while Spring Security expects a UserDetails object from the loadUserByUsername() method.

We will create a converter for this to convert User to UserDetails implementation.

UserToUserDetails.java

This class implements the Spring Core Coverter  interface and overrides the convert() method that accepts a User object to convert. In Line 16, the code instantiates a UserDetailsImpl object, and from Line 19 – Line 26, the code initializes the UserDetailsImpl object with data from User.

With the converter ready, it’s now easy to implement the UserDetailsService interface. The implementation class is this.

Here is our implemention.

UserDetailsServiceImpl.java

In the UserDetailsServiceImpl class, we auto wired in UserService and Converter. In Line 31, the lone overridden method loadUserByUsername() converts a User to UserDetails by calling the convert() method of Converter.

Security Configuration

The current security configuration class, SpringSecConfig extends WebSecurityConfigurerAdapter to configure two things. An authentication provider and the application routes to protect. Our route configuration will remain the same. However, we need to register the DAO authentication provider for use with Spring Security.

We will start by setting up a password encoder to encode passwords present in the UserDetails object returned by the configured UserDetailsService. We will define a new bean for Spring Security’s PasswordEncoder that takes in the StrongPassordEncryptor bean.

Remember that we created StrongPassordEncryptor earlier in the CommonBeanConfig Spring configuration class?

Next, we will set up the DAO authentication provider, like this.

In this code, we passed the previously configured PasswordEncoder and UserDetailsService to daoAuthenticationProvider(). The PasswordEncoder is going to use the Jasypt library for encoding the password and verifying that the passwords match. The UserDetailsService will fetch the User object from the database and hand over to Spring Security as a UserDetails object. In the method, we instantiated the DaoAuthenticationProvider and initialized it with the PasswordEncoder and UserDetailsService implementations.

Next, we need to auto wire in the AuthenticationProvider as we want the Spring Context to manage it.

We will also auto wire in the AuthenticationManagerBuilder. Spring Security will use this to set up the AuthenticationProvider.

The complete SpringSecConfig class is this.

SpringSecConfig.java

Application Bootstrapping with Seed Data

For seed data of the application, we have an ApplicationListener implementation class that gets called upon the ContextRefresedEvent on startup. In this class, we will use Spring to inject the UserRepository and RoleRepository Spring Data JPA repositories for our use. We will create two User and two Role entities and save them to the database when the application starts. The code of this class is this.

SpringJpaBootstrap.java

This class in addition to loading product data, invokes the following methods to load users and roles at startup:

  • loadUsers(): Stores two User entities. One with “user” and the other with “admin” as both the user name and password.
  • loadRoles(): Stores two Role entities for the “USER” and “ADMIN” roles.
  • assignUsersToUserRole(): Assigns the User with username “user” to the “USER” role.
  • assignUsersToAdminRole(): Assigns the User with username “admin” to the “ADMIN” role.

Free Spring TutorialThymeleaf Extras module

In the previous part 5 of this series, I discussed the Thymeleaf “extras” integration module to integrate Spring Security in our Thymeleaf templates. Things will largely remain unchanged in this presentation layer, except for two instances.
Currently, both USER and ROLE are being referred from the presentation layer code as ROLE_USER and ROLE_ADMIN. This was required because we relied on Spring Security’s in-memory authentication provider for managing our users and roles, and Spring Security’s internal feature maps a configured role to the role name prefixed with ROLE_. With the DAO authentication provider, our roles are mapped to authorities as it is (We did this in in the UserToUserDetails converter), and we can refer them directly from code as USER and ADMIN.

The second change is brought in by GrantedAuthority used by the Spring Security UserDetails interface. If you recall, we mapped our Role implementation to SimpleGrantedAuthority in the UserToUserDetails converter.

Therefore, in the Thymeleaf templates, we need to change the hasRole() and hasAnyRole() authorization expressions to hasAuthority() and hasAnyAuthorities().

The affected templates are header.html and products.html.

header.html

products.html

Running the Application

Our application is configured to run the H2 database console, which I have explained here. So, when you run the application, you’ll now be able to access the H2 database console at http://localhost:8080/console. You can use it to view the initial authentication-related data loaded by the SpringJpaBootstrap class.
USER Table for Spring Security
Role Table for Spring Security

This is how the home page appears to authenticated users with USER and ADMIN roles.

Home Page View for USER Role
Home Page View for ADMIN Role

With our Security configuration, this is how the product listing page appears to users with different roles.

Home Page View for Anonymous
Home Page View for USER Role
Home Page View for ADMIN Role

Summary

Spring Security has a large scope, and what we configured is only a small part of it. Spring Security supports XML-based and annotation-based finer level security configurations. With Spring Security, we can secure websites down to specific URLs, assign roles to URL, and even roles to different HTTP actions – a security configuration typically employed in RESTful APIs.

What makes Spring Security great is that you can easily hook in another security provider. If you noticed, we hardly made any change in the presentation and business logic layers while transitioning from the earlier basic in-memory authentication provider to the DAO provider. We could also use LDAP, Single Sign-On (SSO), OpenID, and OAuth 2.0 providers. It all depends on the requirements of your application.

Get the Source!

The full source code for this example is available here on GitHub.

1
Share
, ,

Embedded JPA Entities are nothing new to the JPA standard. By defining Embedded JPA Entities, you can define a common data type for your application. Unlike regular JPA Entities which generally follow a table per entity mapping strategy. Embedded JPA Entities are stored as additional columns in the underlying relational database table.

If you’re using Hibernate as your JPA provider under Spring Boot, and allowing Hibernate to generate the DDL for the database using the default Hibernate naming strategy provided in the default Spring Boot autoconfiguration, you may encounter exceptions when using more than Embedded JPA Entity property in a parent JPA Entity. The Spring Boot default Hibernate naming strategy does not support this. (As of Spring Boot 1.3.0)

I was coding an example for my Spring Core online course, when I ran into this problem.

Here is the exception I received when starting up the embedded Spring Boot Tomcat container.

In a nutshell, the Hibernate Mapping Exception is caused by non-unique column names for mapped to the properties of the Embedded JPA Entities.

One solution to this issue could be to use the @AttributeOverride  annotation to manually provide unique column names for my Embedded JPA Entities. But, looking at the examples in the Oracle documentation, this becomes kind of an eyesore of Annotations on my classes.

AttributeOverride Annotation Example

A More Elegant Solution to Support Multiple JPA Embedded Entities

Looking to escape annotation hell, and Google being my friend, I found a solution on Stackoverflow was to use Hibernate’s DefaultComponentSafeNamingStrategy. This will prepend the column name to the property names of the JPA Embedded Entities.

Spring Boot by default uses SpringNamingStrategy, which overrides HIbernate’s ImprovedNamingStrategy, but adds better support of foreign key naming.

To override the default Spring Boot Hibernate Naming Strategy, you just need to provide the full class name of the Hibernate Naming strategy you wish to use in your Spring Boot application.properties as follows:

application.properties

By overriding the default Spring Boot Hibernate naming strategy I was able to reduce the annotation hell of my JPA mappings.

Embedded JPA Entities Under Spring Boot Example

Here is the complete example of Embedded JPA Entities from my Spring Core Course.

Embedded JPA Entity

Address.java

JPA Entity

Customer.java

Spring Boot Configuration

  • Spring Boot 1.3.0.RELEASE
  • H2 Database (Embedded using Spring Boot defaults)
  • Hibernate 4.3.11 (via Spring Boot Starter Data JPA Maven dependency)

application.properties

Resulting Database Table

h2 database table with embedded jpa entities

Conclusion

I personally feel JPA has enough annotations to make it work. Some days it feels like we traded XML hell for annotation hell. (The more I work with JPA, the more I miss working with GORM in Grails.)

I’m glad I found this cleaner solution for supporting multiple Embedded JPA Entities without wearing out my fingers typing annotations. Hope this helps you along the way!

2
Share
, , ,

This is the 4th part of my tutorial series on building a web application using Spring Boot.  In the the last part of the series, we looked at setting up Spring Data JPA for database persistence. In the second part of the series we looked at using Thymeleaf for building the web pages. And we started off in the first part looking at using the Spring Initializr to start our Spring Boot project.

In this part of the series, we tie everything together to provide a working Spring Boot web application. An application which will display data from the database, and allow you to create new records, update existing records, and delete selected records too.

Spring MVC

In this part of my tutorial series for Spring Boot, we’re going to look at setting up a Spring MVC controller to support CRUD operations against the database.

MVC stands for Model, View, Controller. The MVC design pattern is probably the most popular design pattern used when writing code to generate dynamic web content. This design pattern is not limited to Java nor Spring. The MVC design pattern has been applied in Javascript, PHP, .NET, Python, and many other programming languages. The MVC pattern is popular because it does a great job of separating concerns, and leads you to a clean, maintainable, and easy to understand code base.

MVC Overview

Model

Model refers to a data model, or some type of data structure. For example a web page showing a list of products, the ‘model’ would contain a list of product data.

View

The view layer, in Java frequently a JSP. This will take data from the Model and render the view.

Controller

I like to describe the controller as a traffic cop. It will take an incoming request, decide what to do with it, then direct the resulting action. For example, the controller could get a view product request. It will direct a service to get the product data, then direct to the product view and provide the ‘model’ (product data) to the view.

Single Responsibility Principle Applied to MVC

Frequently when dealing with legacy code, I see a lot of leakage between the layers. JSP pages making database calls. Controllers building database connection pools. On one legacy application I recently worked with the JSP pages and controllers were littered with static method calls, which ultimately made a call to an Oracle database. Because of this, the application was impossible to run outside of the application server. The code was so tightly coupled, there were no unit tests in what is a very large code case. Why? You can’t run any of the code under JUnit because of all the embedded static method calls.

In an MVC application each component has a specific function in life. You should be able to unit test your controllers. Using Mocks, you should be able to unit test that your controller returns the proper model, and makes the proper decisions.

CRUD Operations with Spring MVC

CRUD is a common acronym for Create, Read, Update, and Delete. In the last part of the series, we looked at creating a CRUD repository using Spring Data JPA. In this post, we’ll look at setting up the Spring MVC controller for the corresponding CRUD operations. We’ll continue using the Product class we previously used.

Create

The Create operation is a two step operation. The first step needs to display the create form, the second needs to do the save of the form post.

Here is the controller code for displaying the create product form.

The @RequestMapping  annotation maps the url ‘product/new’ to this controller action. Our controller method is taking in the model attribute. This is the ‘model’ being returned to the view layer.

You can see in the code, we are returning an empty product class to the view. This is more of a trick to re-use the view code for both the Create and Update form. By providing a empty Product object, we reduce the likelihood of null pointer errors when rendering the view. You can either provide an empty object to the model, or do a lot of null checking in the view. From experience, I’ve found this simpler.

Our create view is going to have a form post. We need a controller action to handle this.

In this controller method, we’re handing the form post. The @RequestMapping annotation says to take the ‘url’ ‘product’ and the HTTP request method of POST to map it to this controller method. You can see how we’re asking for a Product object as input to the controller method. One of the cool things about Spring MVC is that it will take your form parameters and automatically bind them to a Product object. The object is automatically created and passed into your controller method. The Spring Framework saves you from the mundane work of parsing out HTTP request parameters.

You can see how we’re using a product service to handle the persistence. This is just a facade to the Spring Data JPA repository we created in the last post. I’m going to skip over the persistence code here. You’ll be able to find it in github. I want you to notice how I’m writing to an interface. The controller doesn’t know about persistence. It does not need to. Storing data is not the job of the controller. Maybe that method is using JDBC. Maybe it is calling a web service. Maybe it’s using JMS. Might be using AQMP. The controller does not care. The controller code does not need to care. This is a great example of decoupling code. Too often I see legacy code where the controllers are doing way too much.

On the last line of the saveProduct method, you can see I’m returning a string with “redirect”. This tells Spring after the save action to redirect to the view to show the created item. This example just show the ‘happy path’ – where everything happens as it should. In a more robust controller you’d have logic not only for the happy path, but to redirect to the create form if validations were to fail.

Read

In Read operations, the client is going to tell you what it wants. In our case, the client will give us an Id value, and we’ll return the corresponding Product.

Read by Id

You can see in our controller method, the Request Mapping is using ‘product’ with a id value in squigglies. This identifies that portion of the url path as an ‘id; value.

Now, we’re using a new annotation @Pathvariable to inject the id value from the url path into our controller as the ID variable. Again, we’re accepting the model variable into our controller. We’re asking the product service to get the product, and the result is appended to the model object, which is returned to the view. The controller method returns a string to indicate which view to render.

List All

A common method is also to provide a list view. Normally, you’re going to want to add paging or some type of filter. However, in this example, we just want to show a simple example of listing products from the database.

We’ve mapped this controller method to the URL ‘/products’. We ask the product service for a list of all products and append it to the model attribute “products”. The controller method returns the string ‘products’ to tell Spring MVC to render the products view.

Update

Updates are actions against existing entities. Updates are similar to create actions, where we have two controller actions involved. With a create, we’re showing a form for a new item, while an update is going to be populated with data from an existing item. While this is very similar to the create action, we typically will want a separate controller action to show the edit form to capture the data for the update.

The good news, functionally the save and view of the saved item is the same as the create action.

Here is our save method once more:

You can see we’re using Spring to bind the form post parameters to a Product object, then calling the product service to save the item. Then just like in the save method of the create process, we want to view the saved product, so we redirect to the show product view.

Delete

There’s a few different ways to implement a delete action. One of the easiest is to use a url with the ID for the delete action. This can then be implemented on the web forms as a simple URL to click on. Below is the controller action for the delete action.

This method will take in the id value from the URL and pass it to the delete method of the product service. Since we’re not creating or updating a product, a typical course of action is to return to the list view. In this example, we redirect to the products view to show the user a list of products.

Summary of CRUD Operations

At this point we’ve covered the necessary controller actions to support CRUD operations on an entity. You can see these operations work in conjunction with the Spring Data JPA methods we looked at in the previous post on Spring Data JPA. I’m using a Facade Service to mask the Spring Data JPA implementation. We’ll take a look at the Facade in the next section.

Free Spring Tutorial

Spring Facade Service

You can see in the controller methods above, there is no dependency on the persistence layer. The controller is completely unaware of how data is being persisted. This is exactly as it should be. Too often I see legacy code where the controller is interacting with the database directly. This is a very poor coding practice. It makes your code tightly coupled and hard to maintain.

Code to an Interface

When using Spring to develop applications it is always best to develop to an interface, especially when leveraging the benefits of dependency injection.  To support our controller actions, I wrote the following interface.

ProductService.java

Notice how this interface is rather generic? Can you tell how data is being persisted? JDBC? Spring Data JPA? Web Service? JMS? This is what decoupling is about. At this point, the answer is all of the above. We just need to provide the appropriate implementation.

Spring Data JPA Product Service Implementation

In the last post of this series, we looked at using Spring Data JPA. Now we need an implementation of the Product Service which will use the Spring Data JPA repositories.

Spring Data JPA Repository

We’ll need to inject an instance of the Spring Data JPA repository into the implementation of our product service. You can do so by declaring a property for the repository and annotating the setter method with the @Autowired  annotation.

List Products

Using Spring Data JPA, it becomes trivial to list all the products for our application. While we did not actually create a findAll()  method on the repository we defined, we inherited by extending the CrudRepository  in Spring Data JPA. This is one of many handy features of Spring Data JPA. It’s going to provide us an implementation of the findAll()  method, which we do not need to write code for.

Get Product (Read)

To fetch a product by its id value, again, we can leverage a method implemented for us by Spring Data JPA.

Save Product (Create / Update)

Spring Data JPA also provides us an implementation of a save method for saving entities. We use this method in creating and updating products in our web application.

Delete Product (Delete)

Finally, in our CRUD operations, Spring Data JPA provides us an implementation of a delete method. Spring Data JPA overloads the delete method, accepting just the ID value, or the entity itself. For our purposes, we are using the ID value to delete the desired entity.

Summary of Spring Data JPA Usage

In this example, we implemented the CRUD operations using a CrudRepository supplied by Spring Data JPA. If you look at the code you will see all we did was extend the Spring Data JPA CrudRepository to create our Product Repository. We did not define, nor implement an additional methods. We’re not declaring transactions. We’re not writing any SQL. I hope you can see the simplicity and time saving using tools like Spring Data JPA can bring you.

Thymeleaf

Thymeleaf Fragments

Thymeleaf fragments are a very powerful feature of Thymeleaf. They allow you to define repeatable chunks of code for your website. Once you define a Thymeleaf fragment, you can reuse it in other Thymeleaf templates. This works great for components you wish to reuse across your web pages.

In developing the Spring Boot Web Application, I found two uses for Thymeleaf templates. The first was common includes of the CSS, Javascript. The second was for a common menu I wanted to display at the top of each web page.

Includes

Below is the Thymeleaf Fragment I’m using for the HTML header includes. You can see its a normal HTML document, using Thymeleaf tags to define the resources for a page.

headerinc.html

Menu

For our Spring Boot Web Application, I chose to use the Bootstrap CSS framework. I’m big fan of Bootstrap. It’s easy to use, and its components look great. Bootstrap CSS has a menu component which I chose to use for the menu system.

In this Thymeleaf fragment, I’m providing the Bootstrap CSS menu I want to place at the top of all my pages. I also have a section to show my Spring Boot logo on each page.

header.html

Including Thymeleaf Fragments

Example

Previously, we defined an index page for our Spring Boot web application. You can apply Thymeleaf templates through the use of HTML comments. By doing this, you preserve the ability of the document to be viewed in the browser. You will be able to see the document okay in your browser, but the fragment portions will be omitted. The fragments are only included when the Thymeleaf template is rendered by Spring.

Remember, Spring will be reading the Thymeleaf templates, then producing output based upon the Thymeleaf directives.

index.html

You can see how our index page is very simple now. While this is a very lean HTML document, when Spring renders it at run time, you will see HTML looking like this:

Actual HTML Rendered to Browser

Notice how Thymeleaf and Spring have merged the contents of the index.html document and the two Thymeleaf fragment documents? Now you have pure HTML, and Thymeleaf tags are not rendered to the HTML content sent to the browser.

The index.html Thymeleaf template will show this page in your browser.

Thymeleaf Index page

Thymeleaf Views for CRUD Application

Show Product

Showing a product is one of the simpler operations under Spring MVC and Thymeleaf. Our controller returned a product object to the model and bound it to the property ‘product’.  Now we can use the typical name-dot-property syntax to access properties of the product object.

This Thymeleaf tag:

Will get text from the description property of the product object and replace the ‘description’ text in the paragraph HTML tag.

Here is the full Thymeleaf template for showing a product:

productshow.html

The show product Thymeleaf template will show this page:

Thymeleaf Show Product Page

List Products

The list view is a little trickier because now we have a list of products to iterate over. Luckily, Thymeleaf makes this very easy to do.

Here is a snippet showing how to iterate over a list of products.

You can see the syntax of this Thymeleaf tag is similar to a for-each loop in Java.

Our controller added a list of products to the ‘products’ property to the model, which we pass to the Thymeleaf tag. The variable name we are assigning to the iterator is ‘product’.

The body of the each tag will be rendered once for each product in the list of products.

Here is the complete Thymeleaf template used for showing a list of products.

products.html

Here is the Thymeleaf list products page:

Thymeleaf List Products

Create / Update Product

We can use the same HTML form for creating and updating products. A little trick is to have your controller method return an empty object to the view for the create option, and the existing object for the update option. By doing this you don’t need to worry about null objects on the view layer. For a new object, the null properties show up blank. For existing objects, non-null properties will get populated into the form fields.

The following line sets up the form in Thymeleaf.

The “th:object” tag binds the product object to the form. Thus, you only use the property names on the form fields. No need to qualify the object name too.

The “th:action” tag maps the form action to the ‘/product’ url. And we specify to use the HTML post action for the form.

Here is the controller action this maps back to:

Notice how we’ve assigned the url ‘product’ and method POST in the request mapping.

This next step is critical for your updates to work properly. All entities have an ID value. This is not accessible for the user to edit, but it still needs to be included to the post back to the server, so Spring / Hibernate can find the correct entity to update. If this is missing, there is no way to distinguish between and update and a create. If the ID property is missing from the form post, Spring Data JPA will think it’s a new item and create a new entity.

The way to handle this is through the use of hidden form fields. In this snippet, we’re assigning hidden fields for the Id and version values. (A best practice in Hibernate is to use a version property to detect conflicting updates.)

Here is the complete product form.

productform.html

Here is the Thymeleaf product form.

Thymeleaf Product Form

Thymeleaf Spring Course
Want to learn more about Thymeleaf, check out my Thymeleaf Spring Course!

Conclusion

In this post we built upon the previous posts in this series on building a web application using Spring Boot to have a functional web application which performs CRUD operations against a single entity. At this point, you can checkout the project from Github and build it using Maven. Spring Boot will create an executable JAR, which you can run to demo the application. Spring Boot will run the application in an embedded Apache Tomcat instance and you will be able to see the application running at http://localhost:8080.

In the next part of this series, I’ll show you how to secure content using Spring Security.
&nbsp:

Free Introduction to Spring Tutorial

Are you new to the Spring Framework? Enroll in my free Introduction to Spring Course!

Get The Source!

Like all of my tutorials, the source code for this post is available on GitHub here.

Save

33
Share
, ,

In the first part of this tutorial series on creating a web application using Spring Boot, I showed how to use Spring Initializr to create the Maven project we’re using in this example. In the second part of the tutorial series, I showed you how to configure Spring MVC and ThymeLeaf templates to display a basic web page via Tomcat. In this part of my Spring Boot tutorial series, we’ll setup the H2 database and Spring Data JPA. We will use these tools to persist data to the database in our Spring Boot Web Application.

Database Persistence with Spring Boot

Spring Boot comes with pre-configured options for relational databases. Like other things in Spring Boot, these are enabled by simply having the dependency on your classpath.

While all the interest in the media is around No-SQL databases, relational databases are time proven work horses. They are not going anywhere soon. If you’re doing enterprise application development with the Spring Framework, you’re probably going to be using a relational database.

Hibernate / JPA does a great job of abstracting the persistence layer. If you want to change from Oracle to DB2 or to MySQL, it is just a matter of changing the database drivers. The JPA mapping code you use on your domain POJOs doesn’t change. Your application code does not change.

NOTE – the above statement is 95% true. When changing databases with complex mappings, you’re going to hit minor edge cases here and there.

When developing Spring applications, it is very common to use a in memory database for your development, and then a real database installation for your testing and production environments. Oracle is a great database, but it’s also BIG and resource intensive. I’ve run Oracle on a laptop. It takes a lot of resources. Its a great database, but its not really meant to run from a laptop.

The persistence API in Java follows the Interface Segregation design principle of object oriented design. So, its easy to plug in a different persistence implementation. With Spring managing the dependency injection for us, it makes swapping databases in and out very easy.

What we are going to do in this tutorial is setup an in-memory database, configure a JPA entity, setup Hibernate to automatically create the database tables, and on startup add data to the database for our use and testing.

By doing this, each time we start our application, we have a newly created database, with known data populated into the database tables. It sounds like a lot of work, but it’s really not much. And it does not add very much to your startup time. With the speed of modern computers, even a complex set of tables and data is going to load in just a few seconds.

The advantage of doing this for you as the developer is you’re working against known data while you are doing your development. It also sets you up for being able to automate integration and functional tests with a continuous build server such as Jenkins.

Free Spring Tutorial
Click Here for my free Spring Course!

H2 Database

The H2 database is a popular database to use when developing Spring applications. H2 is written in Java and is easily runs as an embedded in-memory database. Because it is an embedded in memory database, it makes your build portable. Your build will run anywhere Maven will run.

If you used a database like Oracle or MySQL, now you’ve introduced an external dependency. Your build is no longer portable. If you wanted to do the build under Jekins on a build server, you’d need to install the database on that server or provide a configuration pointing to a database elsewhere.

By using the H2 database as an embedded in memory database, your build remains portable.

H2 Database and Spring Boot

Configuring the H2 database with Spring Boot is very easy. You just need to add the H2 dependency to your Maven Pom. Spring Boot will automatically create the database, setup all the database JDBC objects, and by default configure Hibernate in a create-drop mode. Thus, when Hibernate starts up, it will scan the JPA annotated classes and automatically generate and execute the SQL code needed to create the database tables.

pom.xml

By adding this dependency to your Maven POM, Spring Boot will automatically configure the H2 database.

H2 Database Console

H2 comes with a really cool web based database console you can use to query the database. This is very handy to use when developing with the H2 database and the Spring Framework. When developing the code for this post, I ran into a couple of “gotchas” with setting up the H2 Database Console with Spring Security. It inspired me to write a blog post about it. If you’re following this tutorial step by step, please complete the steps in this post now.

NOTE: When connecting, be sure your JDBC url is set to ‘jdbc:h2:mem:testdb’.

h2 database console

JPA Entities

JPA, which stands for Java Persistence API, is a Java standard. It’s important to remember JPA is just the API (Application Programming Interface) standard. Java itself does not ship with JPA included. For that, you need to include an JPA implementation. There’s number of open source and commercial JPA implementations available.

Free Spring Tutorial
Click here for my free Spring course!

Hibernate and Spring Boot

Hibernate is by far the most popular. When you include the Spring Data JPA dependency in your Maven POM, Hibernate is included by default. As typical with Spring Boot, Hibernate is setup and configured with sensible default properties.

pom.xml

The Spring Data JPA dependencies includes Hibernate. Spring Boot will automatically configure default Hibernate properties.

Example JPA Entity

In our example application, we’re going to use a product for a ecommerce website. I’ll cover JPA mappings in more detail in future posts. Its a subject that could easily be a tutorial series of its own. For now, we just need a product entity.

By convention, I like to put my entity classes in a package called ‘domain’. This is just my personal habit. Probably something I picked up from working so much with the Grails framework.

Product.java

Spring Data JPA

Using Spring Data JPA can save you a lot of time when interacting with the database. Spring Data JPA implements the Repository Pattern. This design pattern was originally defined by Eric Evans and Martin Fowler, in their book Domain Driven Design. This is one of those time test computer science books, over a decade old, still remains relevant today.

You don’t need to use Spring Data JPA for this type of project. But using Spring Data JPA will make your life as a developer easier. A common alternative to Spring Data JPA would be to use the widely accepted DAO pattern, The DAO pattern is very similar to the Repository Pattern. The advantage of using Spring Data JPA is that you’ll be writing a lot less code. Spring Data JPA works a lot like Spring Integration Gateways, where you define an interface, and Spring provides the implementation at run time.

Spring Data JPA CRUD Repository

The Spring Data JPA CRUD Repository is my favorite feature of Spring Data JPA. Similar to coding with a Spring Integration Gateway, you can just define an interface. Spring Data JPA uses generics and reflection to generate the concrete implementation of the interface we define.

Defining a repository for our Product domain class is as simple as defining a interface and extending the CrudRepository interface. You need to declare two classes in the generics for this interface. They are used for the domain class the repository is supporting, and the type of the id declared of the domain class.

For our Product domain class we can define a Spring Data JPA repository as follows.

ProductRepository.java

Integration Testing with Spring Data JPA and JUnit

Even though we are building a web application, we can test the persistence layer without creating a WAR file, and without deploying to Tomcat. We want to set up some integration tests to test our JPA mapping and interactions with the Spring Data JPA repository. To do this, we’re going to take advantage of the auto-configuration options available to us in Spring Boot. By doing this, there is a lot of boilerplate code we don’t need to write.

Spring Data JPA Repository Test Configuration

For our integration tests, we’re going to use a Spring Context to wire up beans to support our tests. If we were not using Spring Boot, we’d need to create a number of beans ourselves. Normally we would need to create:

  • The H2 data source
  • The Hibernate Entity Manager
  • A JPA Transaction Manager

But since we’re using Spring Boot, we don’t need to write code to create these beans. For the purposes of our integration tests for our Spring Data JPA repositories, we can complete our Java configuration with just annotations.

RepositoryConfiguration.java

While this is an empty Java class file, each of the annotations is very important.

  • @Configuration  tells the Spring Framework this is a Java configuration class.
  • @EnableAutoConfiguration tells Spring Boot to do its auto configuration magic. This is what has Spring Boot automatically create the Spring Beans with sensible defaults for our tests.
  • @EntityScan specifies the packages to look for JPA Entities.
  • @EnableJpaRepositories enables the auto configuration of Spring Data JPA.
  • @EnableTransactionManagement Enables Spring’s annotation driven transaction management

Through this configuration, we have everything we need to use the H2 database with Spring Data JPA in JUnit tests.

Spring Data JPA JUnit Integration Test

With our Spring Java configuration done, our JUnit integration test becomes very simple to write. If you’re new to writing JUnit Integration tests with the Spring Framework, checkout this post where I go into this subject much deeper than I am here. Or if you’re new to JUnit, you may wish to start here.

In this post, I am not going to go in depth with Spring Data JPA. This is fairly large and complex project in the Spring Framework. We’re going to use the CRUD repository from Spring Data JPA. CRUD stands for Create, Read, Update, Delete. Your basic persistence operations. Simply extending the Spring Data JPA’s CRUD Repository interface, as we did above, for the specified Entity we will get methods which will:

  • Save an entity
  • Find an entity based on its ID
  • Check if an entity exists based on its ID
  • Get a list of all entities
  • Get a count of all entities
  • Delete an entity
  • Delete all entities

I’ve written a simple integration test for the Spring Data JPA repository I defined above. In the test, I’m going to do some basic operations, like creating an entity, saving an entity, and fetching an entity from the database. While I’ve written a minimal amount of code in this example, the data is really getting saved into a database. You don’t see any SQL happening, but it is getting generated by Hibernate for us. We’re using an in memory H2 database, which goes away once the test is done. But we could easily change the test to save to a database on disk and prove we’ve persisted the test data. Once you grasp how little code you are writing, and how much is happening under the covers for you, you can appreciate what a powerful tool Spring Data JPA is.

ProductRepositoryTest.java

Loading Data Using Spring Data on Startup

Hibernate has a feature to load data on startup. Simply place a file called import.sql on your classpath, and Hibernate will execute the SQL statements in file.

Cool, right?

No, not really. It has us writing SQL statements. What if you’re just doing a prototype? If you change your Entity class, you need to update the SQL. When you’re using Spring Data JPA, this not a very elegant solution. I’m going to shamelessly steal from the Grails community, which has a bootstrap.groovy file which allows us to do things on startup. We have a mature ORM in Hibernate and a really cool tool called Spring Data JPA – why wouldn’t we want to use these tools to load data on startup?

Creating a Product Loader

I previously wrote a post on running code in Spring Boot on Startup. We can use this technique here to utilize the Spring Data JPA repository to populate some data for us to use on startup.

ProductLoader.java

This class implements the ApplicationListner interface, so it gets called upon the ContextRefresedEvent on startup. We’re using Spring to inject the Spring Data JPA repository into the class for our use. In this example, I’m creating two entities and saving them to the database.

ProductLoader.java

Running Product Loader

We still have our Spring Boot application class which was created by the Spring Initializr for us.

SpringBootWebApplication.java

When we run this class, it will startup tomcat for us. In the console log, we can see the output of the log statements from our ProductLoader  class.

To run the Spring Boot application from IntelliJ, simply right click on the SpringBootWebApplication class and select “Run ‘SpringBootWebApplica…'”

run spring boot application from intellij

H2 Database Console

While we still have Tomcat up, We can use the H2 Database Console to browse the H2 database console at the URL http://localhost:8080/console.

Note: If you have not, you will need to setup the H2 database console as explained here.

From the H2 database console, you can see the PRODUCT table has been created by Hibernate, and two records have been inserted via the Spring Data JPA repository we created in this tutorial.

h2 database console showing data saved by Spring Data JPA

Conclusion

In this part of my tutorial series on creating a web application using Spring Boot, I’ve shown you how to setup the H2 database and Spring Data JPA for use. You can see how easy it is to persist data to the database using Spring Data JPA repositories.

In the next part of this tutorial series, I’ll show you how to use data retrieved from the Spring Data JPA repository and display it on a web page using Spring MVC, and how to create and update records.
&nbsp:

Free Introduction to Spring Tutorial

Are you new to the Spring Framework? Checkout my FREE Introduction to Spring Course!.

Get The Code

I’ve committed the source code for this post to github. It is a Maven project which you can download and build. If you wish to learn more about the Spring Framework, I have a free introduction to Spring tutorial. You can sign up for this tutorial in the section below.

The source code for this post is available on github. You can download it here.

Save

1
Share