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
User
Song
Platlist
Keep in mind that we will not have service
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
process-classes
every
And the second one handles the database migration or evolution which I configured what environmentdevelopment
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
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
We define our music streaming table model as below:
As described before, all the validations
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
Song
model by annotating the class with
@Many2Many(other = Playlist.class, join = "playlist_song", sourceFKName = "song_id", targetFKName = "playlist_id")
Many to Many
table name_table name
playlist_song
playlists_songs
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 songfrom playlist_song
table
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/