Categories
Java Spring

How to use ActiveJDBC with Spring Boot

ActiveJDBC is a Java library implements Active record design pattern. It was inspired by ActiveRecord ORM from Ruby on Rails. ActiveJDBC can be used as an alternative to Hibernate in many projects. As long as there is little to no business logic involved. In this article, I demonstrate a comprehensive example of how to use ActiveJDBC with the conjunction of Spring Boot and MySQL 8.

The example of my choice is a music streaming platform where users can create a Playlist Songs like. For that, we will create a set of APIs to perform basic CRUD operations on UserSong Platlist. And to communicate with the database, we will be using ActiveJDBC.

Keep in mind that we will not have service. we follow the Active record pattern and add most of the business logic inside of the models.

Without further ado, let’s get started.

Adding ActiveJDBC dependencies

First thing first, we need to add ActiveJDBC dependency to our project and then do some configurations to make it running.

The first paragraph of the above snippet is rather simple. We just added ActiveJDBC and MySQL connector as the project dependency. But most of the magic comes in the second part of the code where we need to have two maven plugins.

The first plugin generates models and adds them in the classpath. This is necessary, otherwise, the application throws run time exception if does not find instruments To get that working, we need to run a maven goal process-classes everytime before starting the application which is a bit hassle. But don’t worry about it, for now, I have a fix for it which is explained later.

And the second one handles the database migration or evolution which I configured what environmentdevelopment to run and where to find the database configuration. This plugin offers two goals for the initial table creation and gradual migration. Very similar to Liquibase. The plugin keeps track of all executes scripts schema_version.

Unlike the previous plugin, database plugin is optional and can be omitted. But then all the database tables and changes should be done manually.

Database schema

For the music streaming example, we need to create at least four tables, users, songs, playlists, and playlist_song. The last table is required in order to have many to many relationship between song and playlists. As one song can appear in many playlists and one playlist can have many songs.

The final database schema is look like below:

To utilize ActiveJDBC database migrator, we need to place the SQL file inside of migrations src. This is a predefined path.

In order for ActiveJDBC migrator to pick up the script, we need to follow a certain file naming convention such as 20190503131110_create_tables.sql. The format is Year Month Day Hour Minute Second_any description. I’ve tried other format and none has worked. Hence, I assume this is the only format to follow.

Integrating ActiveJDBC with Spring Boot ecosystem

Before starting to implement the code, we need to do one last configuration. And that’s integrating ActiveJDBC with Spring Boot. All we need to do is to create a Servlet filter that opens the database connection before hitting any endpoint and closes after that. This essentially is an optional requirement to reduce code complications. Otherwise, we need to open and close the connection each time manually.

The filter is as follows:

Keep in mind the Servlet filter is not the only option. The same results can be achieved by defining aspects or HandlerInterceptor

Creating models

Now that we have done with the configurations, it’s time to create models for our database tables. Unlike Hibernate, we don’t need to define any property in the models. Solely, extending activejdbc.Model suffices to have a functioning entity.

Keep in mind all the validations need to be done in the model static. ActiveJDBC provides some basic predefined validations as well as allowing to declare and inject yours.

We define our music streaming table model as below:

As described before, all the validations re in static block. Additionally, I defined some column names as the static final variable just for convenience. And also allowing to prepare the object for persistence by accepting parameters in the constructor and setting them inside of the model internally.

The interesting method here is the merge method which I coded for enabling flawless updates which in reality is no difference than create.

It is important to know that Many to Many, we need to create a separate model. And if we don’t follow the naming convention of ActiveJDBC, like this example, we have to define the relationship via annotations in one side of the relation. For our example, we did that in the Song model by annotating the class with

@Many2Many(other = Playlist.class, join = "playlist_song", sourceFKName = "song_id", targetFKName = "playlist_id")

has a naming convention Many to Many which table name_table name However, in our example, we don’t follow that. We simply playlist_song according to the convention should playlists_songs And that is why we override the relationship.

Implementing the Spring Boots controllers

The next which is the last step is to implement the endpoints. These endpoints are not different than normal controllers just they might have some additional logic. One shortcoming of ActiveJDBC is by default it didn’t ship with many validators. One way to compensate that is to use Javax validators in DTOs to disallow end users entering undesirable inputs.

The following is the implementation of our music stream controllers:

Before finishing this post, I’d like to touch down on delete methods in ActiveJDBC. In our example we used three types of delete and each has a different functionality as below:

  • delete: deletes the sole row of the table only. Such as deleting a user or a song.
  • deleteCascade: deletes the row with all its associations entirely. For example, deleting a user row results in removing all the user’s songs and playlists.
  • deleteCascadeShallow: deletes the row and its associated foreign keys. For example, deleting a song results in deleting the foreign key of the song playlist_song as well. But keeps the rest of playlist untouched.

The example source code is available at GitHub at this link: https://github.com/kasramp/active-jdbc-example
All the instructions on how to run the project are provided in the readme file.

Well, that’s all about the ActiveJDBC. Of course, the example presented here was a simple one. You can do much more with ActiveJDBC and use it as a full-blown ORM. In the next article, I’ll discuss the Active Record pattern.

If you are interested about high performance data insertion with Spring Boot and Hibernete have a look at my previous tutorial at below link:
https://geekyhacker.com/2019/03/26/high-performance-data-fetching-using-spring-data-jpa-stream/

Exit mobile version