Reverse Engineering
Reverse engineering is the process of scaffolding JPA entity classes based on a database schema.
Generate entities from a database
Make sure IntelliJ IDEA is connected to your database.
Open the Database tool window, right-click the database, and select
Create JPA Entities from DB….

In the JPA Entities from DB dialog that opens, configure the entity mappings and click OK.
Reverse Engineering Columns
Some developers prefer the DB-first application development approach. First, they add columns directly to the database and then update the JPA model. IntelliJ IDEA can automate this process.
Generate entity attributes from a database
Make sure IntelliJ IDEA is connected to your database.
Open the Database tool window, right-click a table, and select
Create Entity Attributes from DB….

Alternatively, open the Persistence tool window, right-click an entity, and select .
In the JPA Entities from DB dialog that opens, configure the entity mappings and click OK.
Smart References Detection
IntelliJ IDEA deeply understands your model. In certain cases, it's able to properly detect cardinality: @OneToOne, @OneToMany, @ManyToOne, @ManyToMany. The coolest thing is that IntelliJ IDEA can show references even when there are no corresponding columns in the current table.
Let's look more closely at each of these cases.
@OneToOne
There are two situations where we can confidently assume the cardinality of the relation as @OneToOne:
Table has a column with the unique constraint that refers to the primary key of another table
Primary key of the table is a foreign key
Case 1:


IntelliJ IDEA will generate a @OneToOne association with a @JoinColumn annotation in the User entity, and a @OneToOne association with a mappedBy parameter in the Profile entity:
Case №2:


Since @Id should not be a persistence entity, IntelliJ IDEA will generate:
idattribute of a basic type and mark it with@Idannotationusers@OneToOneassociation and mark it with@MapsIdannotation
@OneToMany & @ManyToOne
If a table has the column that refers to the primary key of another table, it is most likely a @ManyToOne association. But you are also able to change cardinality to @OneToOne if required. So, depending on which table you call the reverse engineering action, IntelliJ IDEA will detect mapping type as @OneToMany or @ManyToOne:


IntelliJ IDEA will generate the following code:
@ManyToMany
To establish a many-to-many relationship between two tables, you need to use a junction table. The junction table, in this case, contains only two columns - foreign keys. IntelliJ IDEA can automatically detect such a table and identify the relation cardinality between the two tables whose ids are represented as foreign keys in the junction table as @ManyToMany.


If this association does not exist in any of the entities, IntelliJ IDEA will generate it in the entity for which the reverse engineering action was called.
If this association already exists in one of the entities, then IntelliJ IDEA will generate the @ManyToMany attribute with the mappedBy parameter.
Video tutorials
The following videos demonstrate how to reverse engineer a database schema when the mapping requires some additional configuration.
- Reverse engineer a JPA entity and make it inherit from a parent class
IntelliJ IDEA offers the ability to define a parent entity by selecting a class annotated with
@MappedSuperclassfrom the Parent drop-down box. This allows the generated entities to extend from the parent class and automatically inherit all attributes that have the same name and type.In cases where the column name in the
@MappedSuperclassdoesn't match the child entity's table, we can still inherit the attribute using the@AttributeOverrideannotation. By simply selecting the attribute name and choosing the one to override, IntelliJ IDEA assists in managing the inheritance.
During entity generation, IntelliJ IDEA alerts us if any inherited attributes from the
@MappedSuperclassare missing in the database. To align the model with the database, access the Generate DDL by Entities action in the JPA Structure menu and select the Existing DB update option.- Map a database-specific column type to an entity attribute
For some SQL types, there is no exact match to Java classes. In this case, IntelliJ IDEA does not set the type to prevent generating non-working code. You will need to choose the attribute type yourself. You can also configure default type mappings for each DBMS in the Reference: JPA Reverse Engineering settings.
If you have the HibernateTypes library in your project dependencies list, IntelliJ IDEA can automatically suggest suitable types from the library for the unsupported SQL types during reverse engineering:
- Map database views to entities
IntelliJ IDEA follows all best practices providing the most efficient mapping for DB views while reverse engineering:
As DB views do not have a primary key, IntelliJ IDEA allows you to select a field or a set of fields to use as the identifier for the target entity.
Most DB views are immutable. So, IntelliJ IDEA adds
@Immutableannotation to the entity and generates getters only. This helps to improve application performance.IntelliJ IDEA generates only a no-arg protected constructor for entities that are mapped to a DB view, as per JPA specifications, which prevents developers from creating a new instance of such entities in the business logic code.
Reference: Entities from DB dialog
The JPA Entities from DB dialog lets you map your database tables and views to JPA or Spring Data JPA entities.

The JDBC Entities from DB dialog lets you map your database tables to Spring Data JDBC entities.

General options
The top part of the dialog displays options that apply to all generated entity classes:
Item | Description |
|---|---|
DB connection | Select which database schema you want to reverse engineer. You need to select an existing data source from the Database tool window or create a new one by clicking |
Source root | Select a source root where the generated entity classes should be saved. |
Options | Select which additional data to include in the generated entity classes:
|
Target package | Select a package where the generated entity classes should be saved. |
Other settings | |
Language | Select whether entity classes should be generated in Java or Kotlin. |
The top part of the dialog displays options that apply to all generated entity classes:
Item | Description |
|---|---|
DB connection | Select which database schema you want to reverse engineer. You need to select an existing data source from the Database tool window or create a new one by clicking |
Source root | Select a source root where the generated entity classes should be saved. |
Options | Select which additional data to include in the generated entity classes:
|
Target package | Select a package where the generated entity classes should be saved. |
Language | Select whether entity classes should be generated in Java or Kotlin. |
Entity mapping options
The bottom-left part of the dialog lists tables and views from the selected database, grouped by type and current mapping status:
Mapped Relations: tables and views already mapped to entities. Items that are not fully mapped are labeled with unmapped columns.
Tables: tables not mapped to any entities.
Views: views not mapped to any entities.
When you select a table, view, or relation, the bottom-right part of the dialog lists its mappable elements, also grouped by status:
Mapped Columns: columns already mapped to entity attributes.
Columns: columns not mapped to any entity attributes.
References: foreign keys in other tables that point to this table and are not mapped to any attributes in this table's entity.
For each mappable item, the dialog displays the following options:
Item | Description |
|---|---|
Class name | Specify the name of the generated entity class. IntelliJ IDEA fills this value automatically based on the table name and the JPA Reverse Engineering settings. |
Parent | Select a mapped superclass that will be the parent for the generated entity class. |
ID generation | Select an ID generation strategy for primary keys:
Learn more about ID generation strategies from official Hibernate documentation. |
Id columns | Select which columns should be treated as primary key columns. |
Column/Reference Name | Read-only names of columns in the selected table or view and references to it in other tables. Use the checkboxes to select which columns and references to reverse engineer. |
Attribute | Specify names for the generated entity fields. IntelliJ IDEA fills in these values automatically based on the column name and, if applicable, the JPA Reverse Engineering settings. If you specified a parent class, you can decide for each matching column whether to inherit its attribute from the parent or generate a new one. ![]() If an inherited attribute is not an exact match, the entity will use an @AttributeOverride annotation. |
Mapping Type | Select how to map the column or reference to an entity attribute. For descriptions of all available values, refer to Available mapping types. |
Attribute/Converter/Hibernate Type | Select which attribute types, JPA attribute converters, or Hibernate custom types to use for the generated entity fields. |
The bottom-left part of the dialog lists tables from the selected database, grouped by type and current mapping status:
Mapped Relations: tables already mapped to entities. Items that are not fully mapped are labeled with unmapped columns.
Tables: tables not mapped to any entities.
When you select a table or relation, the bottom-right part of the dialog lists its mappable elements, also grouped by status:
Mapped Columns: columns already mapped to entity attributes.
Columns: columns not mapped to any entity attributes.
References: foreign keys in other tables that point to this table and are not mapped to any attributes in this table's entity.
For each mappable item, the dialog displays the following options:
Item | Description |
|---|---|
Class name | Specify the name of the generated entity class. IntelliJ IDEA fills this value automatically based on the table name and the JPA Reverse Engineering settings. |
ID generation | Select an ID generation strategy for primary keys:
|
Id columns | Select which columns should be treated as primary key columns. |
Column/Reference Name | Read-only names of columns in the selected table and references to it in other tables. Use the checkboxes to select which columns and references to reverse engineer. |
Attribute | Specify names for the generated entity fields. IntelliJ IDEA fills in these values automatically based on the column name and, if applicable, the JPA Reverse Engineering settings. |
Mapping Type | Select how to map the column or reference to an entity attribute. For descriptions of all available values, refer to Available mapping types. |
Attribute Type | Select which attribute types to use for the generated entity fields. |
Available mapping types
The Mapping Type drop-down list lets you select how to map a column or reference to an entity attribute during reverse engineering. The available values depend on whether the item represents ordinary data, a database key, or a reference from another table.
Ordinary columns
Value | Description | Code example |
|---|---|---|
Basic | Map the column to a field of a basic type. |
@Column(name = "status", nullable = false, length = 20)
private String status;
|
Enum | Map the column to a separate enum class and then reference it using the |
Book.java
@Enumerated(EnumType.STRING)
@Column(name = "status", nullable = false, length = 20)
private StatusType status;
StatusType.java
public enum StatusType {
}
|
TODO | Map the column to a field of a basic type, but wrap it in a You can invoke an action from the |
/*
TODO [Reverse Engineering] create field to map the 'status' column
Available actions: Uncomment as is | Remove column mapping
@Column(name = "status", nullable = false, length = 20)
private java.lang.String status;
*/
|
Primary keys
Value | Description | Code example |
|---|---|---|
Basic | Map the column to a field of a basic type and annotate it with |
@Id
@Column(name = "isbn", nullable = false, length = 13)
private String isbn;
|
Composite keys
Value | Description | Code example |
|---|---|---|
EmbeddedId | Map the column to a separate embeddable class and then reference it using the @EmbeddedId annotation. |
BookAuthor.java
@EmbeddedId
private BookAuthorId id;
BookAuthorId.java
@Embeddable
public class BookAuthorId implements Serializable {
@Serial
private static final long serialVersionUID = -8507207156423735624L;
@Column(name = "book_isbn", nullable = false, length = 13)
private String bookIsbn;
@Column(name = "author_id", nullable = false)
private Long authorId;
}
|
IdClass | Map the column to a separate class and then reference it using the @IdClass annotation and |
BookAuthor.java
@IdClass(BookAuthorId.class)
public class BookAuthor {
@Id
@Column(name = "book_isbn", nullable = false, length = 13)
private String bookIsbn;
@Id
@Column(name = "author_id", nullable = false)
private Long authorId;
}
BookAuthorId.java
public class BookAuthorId implements Serializable {
private String bookIsbn;
private Long authorId;
}
|
Foreign keys
Value | Description | Code example |
|---|---|---|
Basic | Map the column to a field of a basic type. |
@Column(name = "publisher_id")
private Long publisher;
|
ManyToOne | Map the column to a reference field with a |
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "publisher_id")
private Publisher publisher;
|
OneToOne | Map the column to a reference field with a |
@OneToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "publisher_id")
private Publisher publisher;
|
TODO | Map the column to a reference field with a relationship annotation, but wrap it in a You can invoke an action from the |
/*
TODO [Reverse Engineering] create field to map the 'publisher_id' column
Available actions: Uncomment as is | Remove column mapping
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "publisher_id")
private Publisher publisher;
*/
|
References in other tables
Value | Description | Code example |
|---|---|---|
ManyToMany | Map the reference to a set and annotate it with |
@ManyToMany
@JoinTable(name = "book_authors", joinColumns = {@JoinColumn(name = "book_isbn")}, inverseJoinColumns = {@JoinColumn(name = "author_id")})
private Set<Author> authors = new LinkedHashSet<>();
|
OneToMany | Map the reference to a set and point to its foreign key attribute in the |
@OneToMany(mappedBy = "bookIsbn")
private Set<Review> reviews = new LinkedHashSet<>();
|
OneToOne | Map the reference to a single field and point to its foreign key attribute in the |
@OneToOne(mappedBy = "bookIsbn")
private Review reviews;
|
The Mapping Type drop-down list lets you select how to map a column or reference to an entity attribute during reverse engineering. The available values depend on whether the item represents ordinary data, a database key, or a reference from another table.
Ordinary columns
Value | Description | Code example |
|---|---|---|
Basic | Map the column to a field of a basic type. |
private String status = "";
|
Enum | Map the column to a separate enum class and then reference it. |
Book.java
@Nullable
private StatusType status;
StatusType.java
public enum StatusType {
}
|
TODO | Map the column to a field of a basic type, but wrap it in a You can invoke an action from the |
/*
TODO [Reverse Engineering] create field to map the 'status' column
Available actions: Uncomment as is | Remove column mapping
private java.lang.String status = "";
*/
|
Primary keys
Value | Description | Code example |
|---|---|---|
Basic | Map the column to a field of a basic type and annotate it with |
@Id
private String isbn = "";
|
Composite keys
Value | Description | Code example |
|---|---|---|
EmbeddedId | Map the column to a separate embeddable class and then reference it. |
BookAuthor.java
@Nullable
@Id
@Embedded.Nullable
private BookAuthorId id;
BookAuthorId.java
@NullMarked
public class BookAuthorId {
private String bookIsbn = "";
private Long authorId = 0L;
}
|
Foreign keys
Value | Description | Code example |
|---|---|---|
Basic | Map the column to a field of a basic type. |
@Nullable
@Column("publisher_id")
private Long publisher;
|
Reference | Map the column to an AggregateReference field. |
@Nullable
@Column("publisher_id")
private AggregateReference<Publisher, Long> publisher;
|
TODO | Map the column to an You can invoke an action from the |
/*
TODO [Reverse Engineering] create field to map the 'publisher_id' column
Available actions: Uncomment as is | Remove column mapping
@Nullable
@Column("publisher_id")
private AggregateReference<Publisher, Long> publisher;
*/
|
References in other tables
Value | Description | Code example |
|---|---|---|
Set | Map the reference to a set and point to its foreign key column in the @MappedCollection annotation. |
@Nullable
@MappedCollection(idColumn = "book_isbn")
private Set<Review> reviews;
|
Single | Map the reference to a single field and point to its foreign key column in the @MappedCollection annotation. |
@Nullable
@MappedCollection(idColumn = "book_isbn")
private Review reviews;
|
Reference: JPA Reverse Engineering settings
The JPA Reverse Engineering settings let you configure how IntelliJ IDEA should map database tables and columns into entities and entity fields during reverse engineering.

Base settings
Item | Description |
|---|---|
Use FetchType.LAZY for @OneToOne and @ManyToOne associations | Set the fetching strategy to |
Use validation annotations (NotNull, Size, etc…) | Annotate entity fields with Jakarta Bean Validation constraints (such as |
Convert the table name to a singular form to generate the class name | When naming entity classes, convert plural table names to their singular form. For example, if a table is named |
Replace ORM references with basic type attributes | Map foreign key columns as basic attributes instead of relationship fields. For example, for a foreign key column named |
Table & column comments
The Table & column comments settings let you select what to do with comments from tables and columns:
@Comment annotation: insert them into Hibernate
@Commentannotations.Java Doc: insert them into Javadoc comments.
Ignore: do not insert them into the code at all.
Naming rules
The Naming Rules settings let you configure how table and column names should be converted into the names of entity classes and fields. This is useful when your database follows specific naming conventions that you do not want to carry over to the generated code, such as prefixes or suffixes.
You can select one of the following strategies:
Configs: configure settings related to prefixes and suffixes:
Item | Description |
|---|---|
Prefixes to skip in table name | Specify which prefixes should be stripped from table names when naming entity classes. For example, if you enter If you want to enter multiple values, separate them with commas. |
Prefixes to skip in column name | Specify which prefixes should be stripped from column names when naming entity fields. If you want to enter multiple values, separate them with commas. |
Suffixes to skip in table name | Specify which suffixes should be stripped from table names when naming entity classes. If you want to enter multiple values, separate them with commas. |
Suffixes to skip in column name | Specify which suffixes should be stripped from column names when naming entity fields. If you want to enter multiple values, separate them with commas. |
Reserved keyword field suffix | Specify which suffix should be appended to the entity field name if it conflicts with a reserved Java keyword. For example, if you set this suffix to |
Algorithm: write custom naming logic in Java. If you select this option, a code editor appears. It includes method stubs that you can adapt to your database's naming conventions.
Mapping types
The Mapping Types settings let you override the default SQL-to-Java type mappings. Depending on your needs, you can map an SQL type to a Java attribute type, a JPA attribute converter, or a Hibernate custom type. This is useful when your application will work with database-specific types, encrypt data, or support multiple database management systems that use different SQL types for the same kind of data.
You can override the type mappings for the following database management systems:
The following video demonstrates how to override a type mapping to use the Hibernate @JavaType annotation: