Spring Boot + Redis + Heroku Demo

The Developer’s Bookshelf with Heroku application utilizes the following database technologies: JPA 2.0, Spring Data JPA, Hibernate, Liquibase, PostgreSQL, H2 embedded, and HikariCP. The source code is available on GitHub.

The Developer’s Bookshelf with Redis migrates that application work to with Redis and Redis To Go while still remaining fully deployable to Heroku. The source code is available on GitHub.

There is a live demo running on Heroku, but keep in mind that it might take 120 seconds to load on the first request.  Please be patient with the first request. Subsequent requests will be normal.

Here is The Developer’s Bookshelf with Redis running on Heroku.

 

Technology Stack

  • Spring Boot, no-xml Spring MVC 4 web application for Servlet 3.0 environment
  • Spring Data Redis
  • Database (Redis, Redis To Go)
  • Thymeleaf templates with added Joda Time & Spring Security Dialects
  • Heroku fully cloud deployable
  • Testing (JUnit/Mockito/MockMVC/AssertJ/Hamcrest)
  • Java 8, Spring Security 3.2, Maven 3, SLF4J, Logback, Bootstrap 3.3.4, jQuery 1.11.2, i18n, etc

 

Migrating from JPA to Redis

Maven Dependencies

In order to utilize the Spring Data Redis project, the following dependency should be added to the pom.xml.

 

Database Configuration

The com.chrisbaileydeveloper.bookshelf.config package holds the database configuration classes for Redis.

DatabaseConfiguration class

The JedisConnectionFactory is injected into this class from either the DevDatabaseConfiguration class or the ProdDatabaseConfiguration class depending on Spring’s active profile.

Redis acts much like a hash table. For this application, the Book domain objects will be saved with a String/Book key-value pair. The Book’s id will be of the string data type, and it will be utilized as the key in Redis.

The StringRedisSerializer and JacksonJsonRedisSerializer<Book> Spring beans make it possible to save the String/Book key-value pairs to the Redis database.

Spring Data JPA offers the Repository abstraction which simplifies often-utilized methods. Spring Data Redis does not offer this functionality. Instead it offers the RedisTemplate in order to simplify database operations.  As shown in the setup of the RedisTemplate, the project will use the string data type for its keys, and Book objects converted to JSON for its values.

 

Persistence Layer

The com.chrisbaileydeveloper.bookshelf.domain package holds the Book domain object.

Here is a snippet from the Book class.

All of the JPA annotations such as @Entity, @Table, @Id, @Version and @Column have been removed from the Book class.   The JSR-349 (Java Bean Validation API) annotations will remain as they will still offer validation functionality.

Note the static long variable longId that will generate new Id’s for the Book objects. The corresponding method generateNextId() will increment and return the next usable Id when a new Book is being created.

 

Repository

The com.chrisbaileydeveloper.bookshelf.repository  package holds the BookRepository class.

With JPA, the BookRepository extended the JpaRepository interface and offered incredible functionality out-of-the-box. As previously discussed, the Spring Data Redis project does not offer the Repository abstraction, but instead offers the RedisTemplate in order to simplify database operations. Therefore as shown above, the BookRepository for Redis requires custom implementation.

 

Service Layer

The com.chrisbaileydeveloper.bookshelf.service package holds the BookService class. Here is a snippet from the class.

All of the @Transactional annotations have been removed as Redis does not support traditional transactions.

 

Controller

The com.chrisbaileydeveloper.bookshelf.controller package contains the BookController class.

The main difference between the JPA and Redis implementations of the controller is during the creation of a new Book.

Here is a code snippet showing the createForm() method for JPA and then for Redis.

JPA

 

Redis

With JPA, if you have set the ‘Id’ attribute to be auto-generated, then an ‘Id’ will be assigned to a Book automatically when it is saved.  With Redis, we manually generate the Book’s Id from a static long variable that increments itself after each new Book is created.

 

Application Configuration

The src/main/resources/config folder holds the main application configuration files. Let’s compare the application-dev.yml configuration files for JPA and Redis.

JPA Configuration

 

Redis Configuration

As shown, the spring.datasource and spring.jpa properties have been replaced by the spring.redis property and its relevant settings.

 

Heroku Configuration

The Procfile for The Developer’s Bookshelf with Heroku contains the following code.

On Heroku, the $DATABASE_URL is a system environment variable that can be accessed by your application. This is quite useful since it means that you will never have to hardcode your database’s username & password into your application.

With Redis, we will be utilizing the Redis To Go Addon and we can then utilize the $REDISTOGO_URL  system environment variable that is available to our application on Heroku. If Spring had a spring.redis.uri  property then we could utilize the Procfile and pass the Redis To Go variable, however such a property does not exist.

Instead, the ProdDatabaseConfiguration class shown below will retrieve the $REDISTOGO_URL system environment variable and parse it to give the JedisConnectionFactory the proper settings in production.

 

Steps for Deployment

The steps required to deploy the migrated Spring Boot + Redis project locally as well as to Heroku are detailed in the project’s GitHub readme.

 

Questions or Clarification

If you have any questions or require any clarification on any parts of the Spring Boot + Redis + Heroku Demo please feel free to contact me.