ORMs are Object Relational Mapping software that are designed to help map data from the database into software objects (vice-versa). I was looking at Kotlin ORMs as I was writing software built on-top of Ktor, a Kotlin server application written by JetBrains. In this post, I will be exploring a few different Kotlin ORMs, specifically Ktorm, a bit of Spring Boot JPA (Hibernate) and JetBrains Exposed.
Initially, I was enticed by the simplicity and neat design of ORM by Ktorm. It uses a very eloquent SQL DSL and also supports Data Access Objects. SQL DSL is something that I wanted to look at since I’ve never tried it before. Although the project does not seem to be the most popular, I decided to give it a try as it might have been a gem waiting to be discovered.
I started writing the schemas and it was nice to code with. Thereafter, I dealt with its interface. In my opinion, I really liked dealing with interfaces more than standard classes.
However, I stumbled when I found out that it does not support the generation of table-creation despite having schemas. This issue was noted in https://github.com/kotlin-orm/ktorm/issues/64. I didn’t quite understand why there is a lack of such an important aspect, especially in an ORM. I would expect ORM to handle these kind of stuff as well and hence, I decided to drop the use of Ktorm.
Spring Boot JPA (Hibernate)
As you know, Spring is one of the most popular Java frameworks out there. It also has support for Kotlin for years now. However, Spring is developed with Java in mind and not focused on Kotlin. Most of it is compatible but there are some caveats, especially with Hibernate.
For example, one of the issues is that Kotlin defaults everything to public while Java defaults everything to package-private. This in turn causes the issue of KT-28525. Other than that, Kotlin properties do not override Java-style getters and setters as noted in KT-6653.
With several other issues in mind, I decided not to use Spring Hibernate to avoid the myriad of Kotlin compatibility issues.
In the end, I looked at Exposed, which is written by the team at JetBrains. It had most of the good stuff I wanted from Ktorm and some of the good stuff I wanted from Spring Hibernate. There were event hooks which I particularly liked as I wanted fields like “updated_at” to automatically update whenever there is a modification to the data object. Other than that, it also supports Kotlinx’s datetime which I wanted.
However, it has some caveats as well. It did not support any form of proper serialization. The easy way of using Kolinx serialization through its decorator ‘@Serializable’ is also not allowed due to how the underlying Exposed entities’ parameters being immutable through ‘final’. This is noted in https://github.com/JetBrains/Exposed/issues/497. Since JetBrains Exposed uses JDBC drivers, it would mean that the communication with the database would be synchronous.
I don’t think the Kotlin eco-system is quite ready yet but in the meantime, I’ll be using some workarounds with JetBrains Exposed. Out of all the 3 ORMs, I think JetBrains Exposed still has the least workarounds required for my scenarios and use-cases.
It is also interesting that Kotlin eco-system is still quite dependent on JetBrains vs how the matured Java eco-system is no longer dependent on Oracle. You can criticise me as I am comparing apples to oranges as Oracle has some fiasco with Java EE whilst JetBrains doesn’t have any major fiasco (yet).