Entity Designer

Introduction

Once you install JPA Buddy, you will find an editor toolbar (1) and additional tool windows (2,3).

JPA Buddy Tool Windows

JPA Buddy provides the following tool windows:

You can customize the appearance of the panel in the designer settings. You have the option to display it together with other panels, as separate panels, integrate it into the standard IntelliJ IDEA panels, or hide it altogether.

JPA Structure

The JPA Structure tab offers a comprehensive, data-centric view of the project. You can use it for various purposes:

  1. Traverse through the data model and observe the entity structure represented hierarchically. This feature allows for easy navigation to entities referencing the current one, as well as ones that the current entity refers to. This is an extremely useful feature, especially for those who are new to an existing project with a large entity graph or for code reviewers who have limited time to understand the data model design.
  2. Create data-related objects: entities, JPA converters / Hibernate types, Spring Data repositories and Liquibase changelog.
  3. Observe related Spring Data repositories, DTOs and projections for each entity.
  4. Edit additional project artifacts such as DB connections, persistence units, and others that the plugin could not detect automatically.

You can set up JPA Structure visibility in visual designer settings.

JPA Palette

The JPA Palette aims to generate appropriate code for the current context. For an entity, it can be an attribute or index; for a repository - a query method, etc.

JPA Palette provides code-generation wizards for the following features:

You can set up JPA Palette's visibility in visual designer settings.

Associations Performance Tips

Hibernate has many relationship mapping types, but not all are equally efficient.

During association creation, JPA Buddy briefly explains why the current configuration is inefficient and may cause performance issues. Use the "Learn more" button to see it.

Also, you can apply optimizations suggested by JPA Buddy. Just select it from a drop-down list with possible options:

JPA Inspector

JPA Inspector is designed to edit existing code: attributes, indexes, queries, etc.

JPA Inspector allows you to configure JPA entities and attributes in it. Click on any element that you need to configure, and change the required properties:

You can set up JPA Inspector visibility in visual designer settings.

Hibernate Validations

For projects with Hibernate Validations, a section appears with validations that you can apply for the selected attribute:

Editor Toolbar

Editor Toolbar contains relevant actions depending on the file content. You can find it on top of the editor window.

You can set up Editor Toolbar visibility in visual designer settings.

Entity Generation

To create a new JPA entity, right-click on the desired folder and select New -> JPA Entity (1). Also, you can create a new entity from the JPA Structure (2) tab:

After that, the following window will appear:

Languages Support

JPA Buddy supports both Java and Kotlin. When JPA Buddy detects the Kotlin dependency in your project, an additional option will appear in the "New Entity" window, letting you pick the language:

Also, in the Settings -> Tools -> JPA Buddy -> Entity Declaration, you can choose which language you want to select by default in the "New Entity" window:

ID and Its Generation Strategy

According to the JPA specification, an ID attribute is required for an entity definition. JPA Buddy allows you to generate this attribute and choose the type (1) and generation strategy (2). Also, you can specify what sequence to use for the Sequence generation strategy (3).

If you want to use an Embedded entity as an ID, JPA Buddy will provide you the list of @Embeddable entities that exist in the project:

Also, you can generate an ID attribute via JPA Palette (1), Editor Toolbar (2) or use a quick-fix (Alt+Enter/⌥ ⏎) (3).

After that, a wizard with more comprehensive customization options will appear:

See the example of the generated ID below:

@Id
@GeneratedValue(
    strategy=GenerationType.SEQUENCE,
    generator = "owners_seq"
)
@SequenceGenerator(
    name = "owners_seq",
    sequenceName = "SEQ_OWNER",
    initialValue = 5,
    allocationSize = 10
)
@Column(name = "id", nullable = false)
private Long id;

Extract to MappedSuperclass

As your application grows and the JPA model evolves, you may realize that certain attributes are common among multiple entities and should be extracted to a @MappedSuperclass for better code organization. JPA Buddy can easily extract methods and attributes along with their JPA annotations to the MappedSuperclass and build a well-designed entity hierarchy.

To achieve this, click on the entity's attribute then navigate to the Entity Designer tab and access the Actions menu or press Alt+Enter/⌥ ⏎ to open the Context Actions menu. From there, select "Extract to MappedSuperclass" as shown below:

Next choose the desired attributes and methods to include in the MappedSuperclass. JPA Buddy will automatically apply the existing annotations to the extracted attributes. Note that any attribute used in the methods will be included as well.

After applying the parameters above, our Pet entity will extend from the following generated class removing the extracted attributes:

//Getters and setters are omitted for brevity
@MappedSuperclass
public class GenericPet {
    @Id
    @Column(name = "id", nullable = false)
    private Integer id;
    
    @Column(name = "name", length = Integer.MAX_VALUE)
    private String name;
    
    @Column(name = "birth_date")
    private LocalDate birthDate;
    
    @ManyToOne(fetch = FetchType.LAZY, optional = false)
    @JoinColumn(name = "type_id", nullable = false)
    private Type type;

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || Hibernate.getClass(this) != Hibernate.getClass(o)) return false;
        Pet pet = (Pet) o;
        return getId() != null && Objects.equals(getId(), pet.getId());
    }

    @Override
    public int hashCode() {
        return getClass().hashCode();
    }
}

Lombok

Inspections

Lombok is a great tool that makes your Java code concise and clean. But there are a few things to consider when using Lombok with JPA. JPA Buddy helps you follow best practices when using Lombok in your JPA entities with a set of inspections:

Avoid using @EqualsAndHashCode and @Data with JPA entities.

Entities are mutable by their nature, so implementing equals() and hashCode() for them is not a trivial task. The implementations provided by Lombok are not well suited for JPA entities and may cause issues with collections and accidental loading of lazy attributes.

Always exclude lazy attributes when using @ToString

By default, @ToString includes all the object fields. Such an approach can have an unwanted side effect for JPA entities: accidentally loading lazy attributes. This can easily harm the application performance or lead to a LazyInitializationException if it happens outside a transaction.

Don't forget to add @NoArgsConstructor to entities with @Builder or @AllArgsConstructor

They introduce their own constructors, so the compiler doesn't generate a default one. A no-argument constructor is required for all JPA entities according to the specification.

Check out our article to learn more about why it is so important to follow the rules above.

Annotations

For projects with Lombok, the JPA Inspector displays a section with possible annotations that you can add to the entity.

Settings

JPA Buddy provides a possibility to generate new entities and attributes with Lombok annotations. To configure which attributes you want to add when creating new entities or attributes, you can select the desired options at the bottom of the Entity Declaration window.

Hibernate

Types & JPA Converters

JPA Buddy helps you generate blanks for JPA Converter or a Hibernate Custom Type via JPA Inspector:

Also, you can create it via JPA Structure. Just click on the "Plus" button and choose JPA Converter or Hibernate Custom Type:

In the Create Custom Type window, you can configure the class name, entity attribute type and database column type.

For JPA Converter you can define whether it will be auto applicable or not.

For Hibernate Custom Type you can set whether it will be possible to alter the behavior of types based on parameters or not.

Here is an example of generated Hibernate Custom Type:

public class BooleanConverter extends AbstractSingleColumnStandardBasicType<Boolean> {
    public BooleanConverter() {
        super(new CharTypeDescriptor(), new BooleanConverterDescriptor());
    }

    @Override
    public String getName() {
        return "BooleanConverter";
    }

    @Override
    public Object resolve(Object value,
                          SharedSessionContractImplementor session,
                          Object owner,
                          Boolean overridingEager) throws HibernateException {
        return null;
    }
}

Event System

Hibernate Event System is a powerful tool that allows you to log or broadcast changes, perform additional checks before irreversible operations, hook business logic when data states change, etc. For all these occasions, Hibernate provides Event Listeners and JPA Buddy helps to scaffold them in a few clicks:

Envers Support

To enable this functionality, add the corresponding dependency to the project.

Use JPA Designer to add the @Audited annotation for both JPA entities and its fields:

Revision Entity

Hibernate stores all versions of the audited entities in a separate table. By default, each new revision will be assigned a revision number and timestamp. If you want to create a custom revision entity and don't have any entities annotated with @RevisionEntity, JPA Buddy provides a convenient dialogue for that.

In the Create Revision Entity wizard, JPA Buddy allows you to specify:

  1. The parent entity (for example, DefaultRevisionEntity or DefaultTrackingModifyingEntitiesRevisionEntity).
  2. The name of the table.
  3. Whether to create a revision listener or choose an existing one.
  4. The required fields for the revision number and timestamp (in case the parent is not specified).
  5. The source root and package where the entity will be saved.

The given configuration will generate the following code:

public class CustomRevisionEntityListener implements RevisionListener {
    @Override
    public void newRevision(Object revisionEntity) {
        CustomRevisionEntity customRevisionEntity = (CustomRevisionEntity) revisionEntity;
        // TODO ("Not yet implemented")
    }
}

@Entity
@Table(name = "revinfo")
@RevisionEntity(CustomRevisionEntityListener.class)
public class CustomRevisionEntity {
    @Id
    @RevisionNumber
    @Column(name = "id", nullable = false)
    private int id;

    @RevisionTimestamp
    @Column(name = "timestamp", nullable = false)
    private long timestamp;

    //getters and setter are omitted
}

Inspections

JPA Buddy provides a lot of inspections that help during coding. By default, all inspections are enabled in all scopes and have warning severity. You can view and configure the complete list of provided inspections in Settings -> Editor -> Inspections -> JPA Buddy.

Settings

Naming Templates

Java code style may change from project to project. Also, working with external databases you have to follow naming conventions for tables, columns, etc., when mapping them to JPA entities. JPA Buddy offers you flexible configurations of naming templates, which are automatically applied to new entities and attributes.

The name that is specified is logical, and the appropriate physical naming strategy will be applied to it. Even if you have specified the name in a certain way, it may be saved to the database with a different one. Learn more about naming strategies in our article. JPA Buddy allows you to choose naming strategies for scripts generation in the settings.

By default, Spring Boot configures the physical naming strategy with SpringPhysicalNamingStrategy. This implementation provides the same table structure as Hibernate 4: all dots are replaced by underscores and camel casing is replaced by underscores as well. Additionally, by default, all table names are generated in lower case. For example, for both of the entity declarations below, the actual name of the DB table will be pet_type.

@Entity
public class PetType {
    // fields omitted
}

or

@Entity
@Table(name = "PetType")
public class PetType {
    // fields omitted
}

Constants Generation

Maintainability is a crucial aspect of any project, and JPA projects often contain numerous Strings that involve JPQL or native query statements, references to attributes, queries, and bind parameter names. According to the best practices, one of the ways to rest your persistence layer well-structured is constants. You can learn about it in Thorben Janssen article.

JPA Buddy provides constants generation for the entity, table, and column names. You can also choose where you want to place constants.

Designer Settings

JPA Buddy comes with a feature-rich tool window in its default mode. However, tool windows may occupy significant horizontal space for users with smaller screens. In such cases, JPA Buddy offers a minimalistic mode as an option. Additionally, JPA Buddy provides settings to fine-tune the appearance of the main visual elements: