Last updated: 2023-03-17

  1. Learn
  2. Documentation
  3. Relation examples

JPA Relationship Types with Examples

This article lists code examples for all relation types of JPA / Hibernate. For this we use the following simple database schema: an Article always belongs to a Blog (N:1), a User can be the author of multiple Articles (1:N), a Blog is always managed by one User (1:1) and a User can have multiple Roles (M:N).

Simple schema with all four JPA relationship types

Simple schema with all four JPA relationship types

Using Bootify, every relationship type can be created and viewed in the browser. Start Project and build your custom database schema - no registration required.

Many-to-one relationship

This link type is certainly the most common. In our example, an Article is associated with exactly one Blog, so a Blog can have several Articles.

Creating a Many-to-one relationship in Bootify

Creating a Many-to-one relationship in Bootify

With these settings selected, the following field is added to the source entity.

New field at the source entity

By default @ManyToOne loads the referenced entity immediately via eager fetching. This should be changed to FetchType.LAZY to avoid oversized queries from Hibernate. The column containing the foreign key is specified with name = "blog_id" - it's based on the field name with an appended "_id".

New field at the target entity

With the attribute mappedBy = "blog" we refer to the field at the source entity that owns and defines the relation. Lazy fetching is already the default for this mapping type, so adding FetchType.LAZY is not necessary. In the code we could now fetch all articles of a specific blog object with blog.getArticles(). Unidirectional relationships do not have the backward mapping.

One-to-many relationship

A One-to-many relationship corresponds to the Many-to-one version - only in reverse direction. Although ownership could theoretically be placed on the from-side, there is practically no use case for this.

Creating our One-to-many relationship

Creating our One-to-many relationship

This results in the following mapping on the from-side, referencing the field at the target entity.

New field at the source entity

The ownership of the relation is on the to-side. The column name is defined in the annotation @JoinColumn again.

New field at the target entity

One-to-one relationship

In our example, each blog is managed by exactly one user. We create this relationship in the following way.

Creating the One-to-one relationship

Creating the One-to-one relationship

In most cases FetchType.LAZY should be used for One-to-one relations as well - unless the automatic loading is explicitly required. In the database there is a foreign key to the referenced table, which would basically also allow repetitions. Therefore we add unique = true to our column definition to create a real One-to-one relation.

New field at the source entity

Hibernate will add the unique constraint by itself. If Liquibase or Flyway is selected for schema generation, Bootify will insert the constraint to the changelog. The target entity also uses the @OneToOne annotation, referencing the specification at the source entity.

New field at the target entity

Many-to-many relationship

For the Many-to-many relation, a table name must also be specified where the role assignments will be stored. If additional fields are required at the intermediate table, it should be explicitly created as a separate entity and interlinked with two Many-to-one relations instead.

Creating our many-to-many relationship

Creating our many-to-many relationship

This results in the following configuration at the from-side. The annotation @JoinTable defines how our "hidden" table looks like. The fields user_id and role_id form the composite primary key.

New field at the source entity

Cascase types are not specified here for now - explicit handling of deletes and updates in the code allows more control and safety against unexpected changes. The backward side simply refers to our already defined mapping.

New field at the target entity

When we call user.getRoles() or role.getUsers() later in the code, Hibernate will perform a query on the user_role table and only returns the linked entities.

In the Bootify Builder a custom database schema including relations can be created. According to the selected database and preferences, the code is generated in such a way that an executable Spring Boot prototype is directly available.

Start Project
No registration required