JPA can behave very differently depending on the exact circumstances under which it is used. Code that works in our local environment or in staging performs very poorly (or even flat out fails) when thrown against real-scale databases in production environments.

Debugging these JPA issues in production is pretty difficult - existing APMs don’t provide enough granular insights at the code level, and tracking every single place someone queried entities one by one instead of in bulk can be a grueling, time-consuming task.

Lightrun is a new approach to debugging in production. Using Lightrun’s Logs and Snapshots, you can now get debugger-level granularity in production without opening inbound ports, redeploying, restarting, or even stropping the running application.

In addition, instrumenting Lightrun Metrics at runtime allows you to track down persistence issues securely and in real-time. Want to see it in action? Check out our 2-minute tutorial for debugging JPA performance issues in production using Lightrun:

>> Debugging Spring Persistence and JPA Issues Using Lightrun

1. Overview

JPA Buddy is a widely used IntelliJ IDEA plugin targeted to both new and experienced developers who work with JPA data model and related technologies like Spring Data JPA, DB versioning tools (Flyway, Liquibase), MapStruct, and some others. The plugin provides visual designers, code generation, and additional inspections that should simplify the development and improve the code according to the best practices for JPA.

The plugin works under both Community and Ultimate versions of IntelliJ IDEA and uses the “freemium” model. Most features are available for free, and we'll need to buy a subscription to access the paid ones.

In this tutorial, we'll look at the plugin's main features and see how we can use them during the application development cycle. As an example, we're going to use the popular reference application – “Spring PetClinic“.

2. Getting Started

We can activate JPA Buddy automatically when adding a JPA dependency to the application source code. The plugin is in the “Recommended InteiilJ Plugins” list, so even if we don't have it installed, IDEA will suggest we do this. We can also install the plugin from IntelliJ's marketplace:

JpaBuddy Notification Window

JPA Buddy functionality may vary depending on the libraries attached to the application. E.g., we won't see menus for DB versioning scripts generation if we have neither Liquibase nor Flyway attached.

3. Working with JPA Entities

Usually, application development starts with the data model. JPA Buddy provides a visual designer and component palette that allows us to create an entity and add basic attributes and associations to it. We can invoke the corresponding action from a context menu or the JPA Structure tool window:

JPABuddy context menu

If we need to add or edit an entity attribute, we can use the JPA palette and inspector. To add an attribute, we need to double-click on it or perform drag-and-drop. The visual editor allows us to define the attribute properties:

Attribute visual editor

To edit an entity's attribute, we can use the JPA inspector. According to JPA specs, the inspector allows us to view and edit almost all options for an entity's attribute. The editor works both ways: when we update an attribute's property, the code is updated. And vice versa, when the entity's code is updated, all changes are reflected in the inspector.

3.1. Lombok Support

According to JPA Specs, entities should have getters and setters for attributes, and this is often treated as “boilerplate” code. Lombok is a popular library that allows us to avoid writing boilerplate and replace it with a couple of annotations. Many developers use Lombok in the JPA entities definition, so JPA Buddy supports it fully. We can edit Lombok-related properties in the JPA Inspector:

Lombok support in inspector

The plugin functionality is not limited to inspection and editing. The important part of the support is inspections. Some Lombok annotations might cause performance issues or unexpected errors when used with JPA. For example, using @ToString annotation might cause LazyInitException because it uses all attributes for an object string representation, including lazy ones.

JPA Buddy shows warnings for such cases and provides quick fixes, and it helps us to avoid bugs in the JPA code:

Lombok code inspection warning

4. DB Migration with Liquibase and Flyway

To create a database from the JPA data model, we usually use DB versioning tools; Liquibase and Flyway are two big players in this area. The most error-prone part of the DB migration process is writing the migration script based on the JPA entity's changes. JPA Buddy provides schema differential script generation for both Liquibase and Flyway. The plugin can compare the existing DB schema to the JPA model or even two schemas:

Migration scripts preview window

In addition to this, JPA Buddy provides scripts autocompletion and smart preview. In this mode, the plugin analyzes the generated scripts and shows a warning if changes can cause failures in the target data source on update:

Warning for a potentially dangerous code

5. Spring Data JPA Support

When the data model is created, the next step is the implementation of the data access repositories. Spring Data JPA is probably the most popular framework for this. JPA Buddy allows us to generate new repositories based on entity definitions. In the repository code, we can use the JPA palette to create various derived methods and queries in a repository code using visual tools:

Spring JPA Repository creation window

For each method, we can change its properties using the JPA inspector. The plugin allows us to add pagination and ordering as well as create projections for a method's return data type:

Spring JPA Repository method inspector

One more useful feature is query extraction. Sometimes derived method names might become too long for complex queries like this:

List<Owner> findDistinctByFirstNameIgnoreCaseOrLastNameIgnoreCaseOrPets_NameIgnoreCaseAllIgnoreCaseOrderByFirstNameAsc(
  String firstName, String lastName, String name);

JPA Buddy analyzes a derived method name and allows us to refactor it by renaming and moving the JPQL query to @Query annotation:

JPA Repository query extraction window
@Query("select distinct o from Owner o left join o.pets pets " +
  "where upper(o.firstName) = upper(:firstName) " +
  "or upper(o.lastName) = upper(:lastName) " +
  "or upper(pets.name) = upper(:name) " +
  "order by o.firstName")
List<Owner> findByAnyName(@Param("firstName") String firstName,
  @Param("lastName") String lastName,
  @Param("name") String name);

6. Entities Generation Based on DB Tables

Data usually outlives the code, so when we build a JPA Data layer over an existing database, we need to create JPA entities based on the current tables. JPA Buddy provides this functionality and allows developers to create entities in a “cherry-pick” manner, selecting tables one by one:

JPA Entity creation wizard

In contrast to the existing solutions, the plugin performs “smart” generation and tries to detect associations between entities. We will generate the corresponding attributes even for OneToMany and ManyToMany entities that are not backed with columns:

Associaton creation on JPA creation

JPA Buddy generates “empty” entities with an ID column only and a TODO comment in the body for such associations. By clicking on this TODO, we can run the column import process for the existing entity:

TODO Action window

7. DTOs and Mappers Generation

DTO is a valuable design pattern for the case of passing data that we cannot map directly to JPA entities. For example, when creating REST API, we might want to expose only some entity attributes.

JPA Buddy can generate DTOs and mappers with the MapStruct library. All we need to do is to select desired attributes for generated DTOs:

DTO Generation window

The plugin generates a DTO and a mapper, including proper mapping for the associations. JPA Buddy supports Lombok for this case too and generates proper annotations for DTOs:

@Data
public class OwnerDto implements Serializable {
   private final Integer id;
   @NotEmpty
   private final String firstName;
   @NotEmpty
   private final String lastName;
   private final List<PetDto> pets;
}

8. Minimalistic Mode

JPA Buddy has a friendly UI, but for those who prefer a “focused” view in IntelliJ IDEA, the plugin provides “minimalistic mode”. We can hide all tool windows and use the keyboard only for entities generation, Spring Data JPA repositories creation and edit, invoke DTO creation wizards, and so on:

JPABuddy minimalistic mode

9. Conclusion

JPA Buddy provides a set of powerful tools that make JPA development easier. The good thing about the plugin is that it supports not only JPA but also related libraries used in data access layer development: Spring Data JPA, MapStruct, Lombok, and DB versioning solutions.

If we consider IntelliJ IDEA Community, this plugin can significantly simplify the work with JPA. IDEA Ultimate users can get some of the JPA Buddy functionality from the bundled plugins for JPA and Spring Framework support. Still, it looks like DB versioning scripts generation and DTOs creation features remain unique in DB development automation.

Persistence bottom
Get started with Spring Data JPA through the reference Learn Spring Data JPA course: >> CHECK OUT THE COURSE
Persistence footer banner
Comments are closed on this article!