So, Hello World... After almost a year of development, the first version of JPA Buddy has finally been released! This is a tool which is supposed to become your faithful coding assistant for projects with JPA and everything related: Hibernate, Spring Data, Liquibase and other mainstream stack.
“Why would I use it?” - this is a fair question towards any new tool or framework. In short, if you use JPA for data persistence, JPA Buddy will help you to be more efficient. In this article, I'll present an overview of the tool. I hope it will take its fair place among the most loved tools for Java developers, ones who use JPA, Spring, Liquibase and of course the most advanced Java IDE - IntelliJ IDEA.
The Story Behind
We are the creators of CUBA Platform (btw, a few weeks ago it was renamed to Jmix:)) - a rapid application development environment on Java. CUBA Platform is quite a unique product. It has both parts: a framework and a development tool. One of the most loved parts of CUBA Studio (specialized IDE for CUBA) is "Entity Designer" - it amazed over 20 000 members of CUBA community by how easy and fast anyone can design their data model. Even for those who have never heard of JPA, things like creating JPA entities, constraints, DDL scripts become a no-brainer.
Since 2016, when CUBA went open-source we have participated in dozens of conferences all around the world, gathering feedback and getting a better understanding of what developers need. And one of the most annoying questions was - "Can we use your entity designer in our application without CUBA?". I'm happy to announce that with JPA Buddy we managed to change our negative answer towards... yes!
JPA Buddy is noninvasive, it doesn't require any extra dependencies - it is a tool and only a tool. This means you can gain benefits from it not only for new but also for already existing projects which employ JPA for the persistence layer. It works as an addition to your IntelliJ IDEA enabling a number of JPA-related features. JPA Buddy helps you to generate code, find and fix potential bugs, refactor and perform other laborious boilerplate operations.
Before JPA Buddy got its first line of code we had conducted a survey in order to gather various use cases of JPA and surrounding technology. The result doesn't look very surprising - an average application nowadays is a Spring Boot application with Hibernate as an ORM implementation, Spring Data JPA as the data manipulation mechanism and Flyway or Liquibase for the database migration system. Ah, almost forgot about Lombok... This technology stack became our main focus for the first release.
Speaking about the aim of the instrument we pursued the following targets:
- Minimize manual boilerplate coding - the tool should generate code that you would write manually but faster
- Save time on reading the documentation - the tool must provide intuitive and self-explanatory visual designers
- Leave freedom of choice - the tool must not dictate any particular coding style, but provide various options
- Detect potential issues and provide ways to fix the most common problems - the tool should alert a developer about such problems as early as possible, ideally at the coding stage, not in runtime
- Provide a data-centric view on a project and convenient navigation between related objects
For the first release we were able to deliver quite a significant number of features covering most aspects of data model development. Good news for those who use Liquibase - it is implemented and available in the first release of JPA Buddy. Not so good news for Flyway users - it is in the high-priority list of features.
In longer-term planning we are going to introduce the following set of features:
- Hibernate-specific annotations, like
@Where, @NaturalId, @Formula, Hibernate search ones and others…
- Visual query designer
- Audit using Envers and Spring Data JPA
- Reverse engineering of a database schema
- Support for Kotlin
There are also some features we also keep in mind on the second stage: Quarkus and Micronaut support, REST API and UI generation for CRUD operations.
As you may see, there is a long way ahead and we would much appreciate your help in prioritizing all above features - don't hesitate to let us know your point of view via our contact form, Twitter or join Discord chat.
Let me give a short overview of what it looks like. Since you install JPA Buddy you will find 3 additional tool windows: JPA Structure, JPA Palette and JPA Inspector.
JPA Structure is always available on the bottom-left side. It provides a comprehensive data-centric view on the project. You can use it for many different purposes:
- Traverse through the data model. The entity structure is represented in a hierarchical way. You can easily observe and navigate to entities referencing the current one and ones the current entity refers to. This is an extremely useful feature, especially for those who are just diving into an existing project with a large entity graph or for code reviewers, who often see parts of the data model for the first time and have limited time to understand how it is designed.
- Create data-related objects: entities, JPA converters / Hibernate types, Spring Data repositories and Liquibase changelog.
- Observe related Spring Data repositories for each entity.
- View Liquibase changelogs along with their internal structure for easier navigation.
- Specify plugin-related settings such as DB connection, persistence units and others, which the plugin was not able to detect automatically.
More features to come…
JPA Palette and Inspector
JPA Palette is sitting at the top right and its content is context-dependent. It is available only when Buddy is ready to offer something for fast code generation. Currently, the tool comes up when editing following objects: JPA Entity, Spring Data repository and Liquibase changelog. Simply find the desired option from the list and double-click on it!
JPA Inspector is placed at the bottom right, beneath the Palette and becomes visible and invisible synchronously with it. The Inspector is also context-dependent. While the Palette gives you a number of options for generating new parts of code, the Inspector is intended to modify already existing code. Here you can see what capabilities you have to tune a selected part of code, e.g. a field of an entity or a statement from a Liquibase changeset.
These features are much helpful for both newbies and experienced users. Juniors can evaluate the full list of options, pick the proper one and generate valid code using intuitive visual designers. Seniors often forget minor things that are not in daily use and Buddy will save a few seconds of their valuable time on searching through the documentation in order to remember the right annotation or syntax.
Good news for those who use Liquibase as a database schema versioning solution. JPA Buddy provides tight integration with it, enabling convenient changelog editing, smart changelogs generation and flexible type management.
First of all, you get a visual designer for editing changelogs. Explore various available commands in the Palette and use the Inspector toolwindow to see different settings that could be applied for the selected statement.
Secondly, you can define your own mappings to match Java types (Converters/Hibernate types) and the ones that should be used for each specific DBMS. Let me give you a few examples, when this feature will be extremely useful:
- Using a byte array entity field, Hibernate scheme generator as well as Liquibase would map your Byte to a quite exotic type OID. I guess quite a few developers would prefer to use bytea instead of the defaultly proposed type. This could be easily solved by specifying bytea as a desired mapping type for byte.
- Using a JPA converter or a Hibernate custom type causes unpredictable behaviour or even failures in Hibernate scheme generator and Liquibase changelog generator. You can define the right type in JPA Buddy to resolve this issue.
- Using a String field we may want to map it to nvarchar instead of the default varchar.
All these cases could be traditionally solved by using the columnDefinition attribute, however, this solution would not work for cross-DBMS solutions.
Finally, the most time-saving feature: Liquibase changelogs generator. From my experience (proved by the previously-mentioned survey) there are two major ways of creating Liquibase changelogs:
- Writing changelogs manually.
- Generating scripts by comparing two databases, source one (representing the actual state of the model) against the target one (with the previous state of the model).
For those who prefer the first option JPA Buddy enables the already mentioned changelog designer.
The second option seems to be the most used one. So, we compare two databases. The target database is relatively easy to obtain, for instance we can simply create a dump of the production environment. Problems come with the source database. Let's start with a minor issue: it may happen that the database used for development on the developer's laptop is not the same DBMS type as the production one. Well, this can be solved by, for example, running MS SQL in Docker on Mac. More serious thing is that it is hard to find a "clean" source database, as it normally gets formed while development by the Hibernate schema generator. Often, this leads to a bunch of garbage tables and attributes, which finally appear in the production DB. To avoid such junk you would need to spend another hour or two reviewing your database schema before running generation of the changelogs.
JPA Buddy offers an admirable function of generating changelogs directly by comparing your JPA entities with the target database (or a snapshot of the target database). You can run H2 for the development purposes and still provide correct changelogs for Oracle or MS SQL or whatever you use in production. This ensures that if you have garbage in changelogs, this is exactly garbage you have in your source code. All you need is to keep your data model clean and be sure that migration will not bring unwanted artefacts to the production database.
Another feature of the changelogs generator is the ability to filter resulting statements into 3 categories:
- containing only safe statements, ones which cannot fail while update or ruin your application, e.g. adding a new column
- containing statements that may fail while update, but not lead to data-loss, e.g. applying a unique constraint
- containing statements that will cause data-loss, e.g. dropping a table or a column
You decide how to split such statements: put them into separate changelogs or just tag them with some label or context.
This article presents an overview of the very first release of JPA Buddy. Obviously, as any brand new product it cannot avoid some issues and defects. Today the main focus is polishing the existing functionality, detecting and implementing essential features we miss. Directly speaking, we would like to inspire you to become an early adopter and form an initial community of enthusiasts. Install JPA Buddy, try it out and share your feedback with the development team - this will help a lot to steer the product towards the right direction!