How I built my first Kotlin-VertX-Hibernate stack

I've been using Kotlin for close to 6 months now, and have been experimenting with quite a number of frameworks trying to find the combination that will allow me the most flexibility as well as great performance.

Since I've used Spring Boot previously, and ran into a few troubles after trying to do things which the framework didn't support, I steered clear of it. Spring5, which supports asynchronous operations, only reached Milestone 1 when I was in the market for a new framework. So, I parked it until it was stable enough for production use.

DropWizard looked like a decent option as well, considering its use of Jersey, Jetty, Jackson, and Metrics.

JDBI + Liquibase made for decent choices, to take care of the DB layer, but I needed Hibernate for the having to switch between MySQL, SQLServer, and PostgreSQL. Since a lot of my existing logging infrastructure depends on Log4j, having to hack around to see how I can replace Logback, did not seem like a good use of my time.

I've been sharing articles about VertX from time to time, including spectacular benchmarks, but haven't used it myself until now. So, I wanted to see how easy it would be to write a complete system in Kotlin + VertX, and how complex it would be, compared to the other alternatives I've listed above.

Maybe you can be the judge of the ease of the aforementioned setup. Let's start with a basic maven pom.xml in the root directory ...

We would be using 3.3.3 for this demo (note that a Kotlin specific version of VertX will be released in early 2017, for now we're using VertX Java inside Kotlin)

<properties><vertx.version>3.3.3</vertx.version></properties>

And that's most of the XML boilerplate - you can always switch to gradle if you prefer to get away from the maven boilerplate.

Now in your src/main/java directory (you can also use src/main/kotlin if you prefer, but that would require us to configure the Maven Kotlin plugin, to look for source files in that directory), create a HashnodeDemo.kt file and add the following code to the file:

Now if you run this class from your IDE (I'm using IntelliJ, so for me it's right-click and Run HashnodeDemo), and open your browser at localhost:9090, you should see Hello World :-) in your browser.

So, with a single pom.xml file, and a single Kotlin object we've got a web server that can respond to GET requests. Nothing fancy yet, but as you would see further on, VertX mostly gets out of your way allowing you almost full control of the response going back.

Handling WebSockets can also be done with extra minimal code, but I'll cover that in more detail in a future post:

VertX, just like NodeJS, uses an event-loop, and at no point should the event-loop be blocked. If you do block it, expect lots of warnings in your logs, and a poor performance. Fortunately, VertX gives you a mechanism out of the box that will allow you to handle blocking requests with ease.

To demonstrate, let's add some ASCII art that will displayed when the application starts. In src/main/resources, create ascii.txt and add some ASCII art to it:

During startup, the blocking call to the file-system would run in a worker pool while the rest of VertX continues to run asynchronously — best of both worlds; handling an asynchronous request, while still being able to make use of blocking calls in the background...

Now before you follow this tutorial and add Hibernate to your project, consider the vast array of options available. Hibernate, in my opinion, is the most feature-complete ORM out there, but that also makes it the heaviest ORM available. Other options include:

JDBI looks decent if you just want to write normal SQL queries, by hand, and need help in
binding params and results

VertX JDBC is very bare-bone, and will probably require lots of work
on your side, depending on what you are looking for

ReQuery comes bundled with RxJava out of the box, and feels almost like Hibernate,
but it's much more lightweight

The hibernate.dialect sets the flavour of SQL you are running. We would be using MySQL with InnoDB for this demo. hibernate.hbm2ddl.auto can be set to validate, to validate the database against the current database model; update will update your database based on your model; whereas create-drop will recreate your database effectively every time your restart.

Set hibernate.hbm2ddl.auto to validate when going to production, otherwise you might just drop / corrupt your production database.

The JDBC Config is simply where you configure the location of your database, username, and password.

The Connection Pool section allows us to setup a connection pool, in this example we set it to use only 5 connections at maximum. If your application is the only application connecting to the database, you can set that close to the maximum number of connections your database can handle. Just remember that those connections will be kept open as long as the application is running.

Let's create a few Hibernate models — first, let's create a base model so that we don't have to re-declare all the basic fields in all the models we create. Create a new directory src/main/java/com/hashnode/demo/model

This setup would give you a very quick startup time, but Hibernate will only startup after the first query has been fired, meaning your first user will get a very slow response. To fix that, we make a dummy query which would force Hibernate to start in the background.

Any new entities, which you want to create (or update), should always be in a transaction block. This can be done in a one-liner (remember, if you don't specify the lambda-variable in Kotlin, it defaults to it)

transaction { it.persist(Company(name = "another company")) }

Remember that JDBC is blocking, so any Hibernate queries should be run using vertx.executeBlocking. This is typically how you would structure it, either pass in the ServerWebSocket; or the Route, if you're using the REST (GET, POST, etc...) methods. Execute the query inside the executeBlocking section, and write the result back in the second lambda.

How you structure your files, is completely up to you. You could even use extension methods to cut down on the boilerplate, but you do have the option to structure things according to how they suit you the best.

As I've shown, Kotlin to VertX, works like a well-fitting glove to a hand. Adding an ORM-layer is straight-forward as well. I've also demonstrated the addition of Hibernate, which in my case was the right choice for the stack that I work on. If you don't need to jump between databases, and prefer something more lightweight, be sure to check out the other options I have mentioned above.

If you have any questions, feel free to post them here, and I'll respond when time allows.

A few small suggestions. Vert.x web Router has a 'blockingHandler' so that you don't need the extra calls to 'executeBlocking', and therefore have simpler code. Secondly, you can pass the instance of EntityManagerFactory to your verticles in a constructor and use it in any of your code as long as it is declared 'final'. Finally, you could have a 'Main class which starts your Vert.x app by calling 'Vertx.vert()' and do your blocking configuration (Hibernate/LiquiBase/etc...) before you deploy your first Verticle.

Good work and nice write up! But the end result compared to what you'd get with Spring repositories and annotations is much more cluttered. I understand that you went down this path until Spring 5 stable is released but when that happens I don't see any reason someone would go with vertx+hibernate instead of that.

Great idea. I'm sure many people would be interested including myself. I also would like to see kotlin coroutines with vertx APIs. They have been nicely integrated with spring 5 github.com/alek-sys/spring-coroutines-demo