Baeldung Pro – NPI EA (cat = Baeldung)
announcement - icon

Baeldung Pro comes with both absolutely No-Ads as well as finally with Dark Mode, for a clean learning experience:

>> Explore a clean Baeldung

Once the early-adopter seats are all used, the price will go up and stay at $33/year.

Partner – Microsoft – NPI EA (cat = Baeldung)
announcement - icon

Azure Container Apps is a fully managed serverless container service that enables you to build and deploy modern, cloud-native Java applications and microservices at scale. It offers a simplified developer experience while providing the flexibility and portability of containers.

Of course, Azure Container Apps has really solid support for our ecosystem, from a number of build options, managed Java components, native metrics, dynamic logger, and quite a bit more.

To learn more about Java features on Azure Container Apps, visit the documentation page.

You can also ask questions and leave feedback on the Azure Container Apps GitHub page.

Partner – Microsoft – NPI EA (cat= Spring Boot)
announcement - icon

Azure Container Apps is a fully managed serverless container service that enables you to build and deploy modern, cloud-native Java applications and microservices at scale. It offers a simplified developer experience while providing the flexibility and portability of containers.

Of course, Azure Container Apps has really solid support for our ecosystem, from a number of build options, managed Java components, native metrics, dynamic logger, and quite a bit more.

To learn more about Java features on Azure Container Apps, you can get started over on the documentation page.

And, you can also ask questions and leave feedback on the Azure Container Apps GitHub page.

Partner – Orkes – NPI EA (cat=Spring)
announcement - icon

Modern software architecture is often broken. Slow delivery leads to missed opportunities, innovation is stalled due to architectural complexities, and engineering resources are exceedingly expensive.

Orkes is the leading workflow orchestration platform built to enable teams to transform the way they develop, connect, and deploy applications, microservices, AI agents, and more.

With Orkes Conductor managed through Orkes Cloud, developers can focus on building mission critical applications without worrying about infrastructure maintenance to meet goals and, simply put, taking new products live faster and reducing total cost of ownership.

Try a 14-Day Free Trial of Orkes Conductor today.

Partner – Orkes – NPI EA (tag=Microservices)
announcement - icon

Modern software architecture is often broken. Slow delivery leads to missed opportunities, innovation is stalled due to architectural complexities, and engineering resources are exceedingly expensive.

Orkes is the leading workflow orchestration platform built to enable teams to transform the way they develop, connect, and deploy applications, microservices, AI agents, and more.

With Orkes Conductor managed through Orkes Cloud, developers can focus on building mission critical applications without worrying about infrastructure maintenance to meet goals and, simply put, taking new products live faster and reducing total cost of ownership.

Try a 14-Day Free Trial of Orkes Conductor today.

eBook – Guide Spring Cloud – NPI EA (cat=Spring Cloud)
announcement - icon

Let's get started with a Microservice Architecture with Spring Cloud:

>> Join Pro and download the eBook

eBook – Mockito – NPI EA (tag = Mockito)
announcement - icon

Mocking is an essential part of unit testing, and the Mockito library makes it easy to write clean and intuitive unit tests for your Java code.

Get started with mocking and improve your application tests using our Mockito guide:

Download the eBook

eBook – Java Concurrency – NPI EA (cat=Java Concurrency)
announcement - icon

Handling concurrency in an application can be a tricky process with many potential pitfalls. A solid grasp of the fundamentals will go a long way to help minimize these issues.

Get started with understanding multi-threaded applications with our Java Concurrency guide:

>> Download the eBook

eBook – Reactive – NPI EA (cat=Reactive)
announcement - icon

Spring 5 added support for reactive programming with the Spring WebFlux module, which has been improved upon ever since. Get started with the Reactor project basics and reactive programming in Spring Boot:

>> Join Pro and download the eBook

eBook – Java Streams – NPI EA (cat=Java Streams)
announcement - icon

Since its introduction in Java 8, the Stream API has become a staple of Java development. The basic operations like iterating, filtering, mapping sequences of elements are deceptively simple to use.

But these can also be overused and fall into some common pitfalls.

To get a better understanding on how Streams work and how to combine them with other language features, check out our guide to Java Streams:

>> Join Pro and download the eBook

eBook – Jackson – NPI EA (cat=Jackson)
announcement - icon

Do JSON right with Jackson

Download the E-book

eBook – HTTP Client – NPI EA (cat=Http Client-Side)
announcement - icon

Get the most out of the Apache HTTP Client

Download the E-book

eBook – Maven – NPI EA (cat = Maven)
announcement - icon

Get Started with Apache Maven:

Download the E-book

eBook – Persistence – NPI EA (cat=Persistence)
announcement - icon

Working on getting your persistence layer right with Spring?

Explore the eBook

eBook – RwS – NPI EA (cat=Spring MVC)
announcement - icon

Building a REST API with Spring?

Download the E-book

Course – LS – NPI EA (cat=Jackson)
announcement - icon

Get started with Spring and Spring Boot, through the Learn Spring course:

>> LEARN SPRING
Course – RWSB – NPI EA (cat=REST)
announcement - icon

Explore Spring Boot 3 and Spring 6 in-depth through building a full REST API with the framework:

>> The New “REST With Spring Boot”

Course – LSS – NPI EA (cat=Spring Security)
announcement - icon

Yes, Spring Security can be complex, from the more advanced functionality within the Core to the deep OAuth support in the framework.

I built the security material as two full courses - Core and OAuth, to get practical with these more complex scenarios. We explore when and how to use each feature and code through it on the backing project.

You can explore the course here:

>> Learn Spring Security

Course – All Access – NPI EA (cat= Spring)
announcement - icon

All Access is finally out, with all of my Spring courses. Learn JUnit is out as well, and Learn Maven is coming fast. And, of course, quite a bit more affordable. Finally.

>> GET THE COURSE
Course – LSD – NPI EA (tag=Spring Data JPA)
announcement - icon

Spring Data JPA is a great way to handle the complexity of JPA with the powerful simplicity of Spring Boot.

Get started with Spring Data JPA through the guided reference course:

>> CHECK OUT THE COURSE

Partner – LambdaTest – NPI EA (cat=Testing)
announcement - icon

End-to-end testing is a very useful method to make sure that your application works as intended. This highlights issues in the overall functionality of the software, that the unit and integration test stages may miss.

Playwright is an easy-to-use, but powerful tool that automates end-to-end testing, and supports all modern browsers and platforms.

When coupled with LambdaTest (an AI-powered cloud-based test execution platform) it can be further scaled to run the Playwright scripts in parallel across 3000+ browser and device combinations:

>> Automated End-to-End Testing With Playwright

Course – Spring Sale 2025 – NPI EA (cat= Baeldung)
announcement - icon

Yes, we're now running our Spring Sale. All Courses are 25% off until 26th May, 2025:

>> EXPLORE ACCESS NOW

Course – Spring Sale 2025 – NPI (cat=Baeldung)
announcement - icon

Yes, we're now running our Spring Sale. All Courses are 25% off until 26th May, 2025:

>> EXPLORE ACCESS NOW

1. Overview

Java Persistence API (JPA) is an Object-Relational Mapping (ORM) specification for Java applications. Further, Hibernate is one of the popular implementations of the JPA specification.

Associations are a fundamental concept in ORM, allowing us to define relationships between entities. In this tutorial, we’ll discuss the differences between unidirectional and bidirectional associations in JPA/Hibernate.

2. Unidirectional Associations

Unidirectional associations are commonly used in object-oriented programming to establish relationships between entities. However, it’s important to note that in a unidirectional association, only one entity holds a reference to the other.

To define a unidirectional association in Java, we can use annotations such as @ManyToOne, @OneToMany, @OneToOne, and @ManyToMany. By using these annotations, we can create a clear and well-defined relationship between two entities in our code.

2.1. One-To-Many Relationship

In a one-to-many relationship, an entity has a reference to one or many instances of another entity.

A common example is the relationship between a Department and its Employees. Each Department has many Employees, but each Employee belongs to one Department only.

Let’s take a look at how to define a one-to-many unidirectional association:

@Entity
public class Department {
 
    @Id
    private Long id;
 
    @OneToMany
    @JoinColumn(name = "department_id")
    private List<Employee> employees;
}

@Entity
public class Employee {
 
    @Id
    private Long id;
}

Here, the Department entity has a reference to a list of Employee entities. The @OneToMany annotation specifies that this is a one-to-many association. The @JoinColumn annotation specifies the foreign key column in the Employee table referencing the Department table.

2.2. Many-To-One Relationship

In a many-to-one relationship, many instances of an entity are associated with one instance of another entity.

For example, let’s consider Student and School. Each Student can be enrolled in one School only, but each School can have multiple Students.

Let’s take a look at how to define a many-to-one unidirectional association:

@Entity
public class Student {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String name;

    @ManyToOne
    @JoinColumn(name = "school_id")
    private School school;
}

@Entity
public class School {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String name;
}

In this case, we have a many-to-one unidirectional association between Student and School entities. The @ManyToOne annotation specifies that each student can be enrolled in only one school, and the @JoinColumn annotation specifies the foreign key column name to join the Student and School entities.

2.3. One-To-One Relationship

In a one-to-one relationship, an instance of an entity is associated with only one instance of another entity.

A common example is the relationship between an Employee and a ParkingSpot. Each Employee has a ParkingSpot, and each ParkingSpot belongs to one Employee.

Let’s take a look at how to define a one-to-one unidirectional association:

@Entity
public class Employee {
 
    @Id
    private Long id;
 
    @OneToOne
    @JoinColumn(name = "parking_spot_id")
    private ParkingSpot parkingSpot;
 
}

@Entity
public class ParkingSpot {
 
    @Id
    private Long id;
 
}

Here, the Employee entity has a reference to the ParkingSpot entity. The @OneToOne annotation specifies that this is a one-to-one association. The @JoinColumn annotation specifies the foreign key column in the Employee table that references the ParkingSpot table

2.4. Many-To-Many Relationship

In a many-to-many relationship, many instances of an entity are associated with many instances of another entity.

Suppose we have two entities – Book and Author. Each Book can have multiple Authors, and each Author can write multiple Books.  In JPA, this relationship is represented using the @ManyToMany annotation.

Let’s take a look at how to define a many-to-many unidirectional association:

@Entity
public class Book {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String title;

    @ManyToMany
    @JoinTable(name = "book_author",
            joinColumns = @JoinColumn(name = "book_id"),
            inverseJoinColumns = @JoinColumn(name = "author_id"))
    private Set<Author> authors;

}

@Entity
public class Author {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String name;
}

Here, we can see a many-to-many unidirectional association between Book and Author entities. The @ManyToMany annotation specifies that each Book can have multiple Authors, and each Author can write multiple Books. The @JoinTable annotation specifies the name of the join table and the foreign key columns to join the Book and Author entities.

3. Bidirectional Associations

 A bidirectional association is a relationship between two entities where each entity has a reference to the other.

In order to define bidirectional associations, we use the mappedBy attribute in the @OneToMany and @ManyToMany annotations. However, it’s important to note that only relying on unidirectional associations may not be sufficient, as bidirectional associations provide additional benefits.

3.1. One-To-Many Bidirectional Association

In a one-to-many bidirectional association, an entity has a reference to another entity. Additionally, the other entity has a collection of references to the first entity.

For instance, a Department entity has a collection of Employee entities. Meanwhile, an Employee entity has a reference to the Department entity it belongs.

Let’s take a look at how to create a one-to-many bidirectional association:

@Entity
public class Department {
 
    @OneToMany(mappedBy = "department")
    private List<Employee> employees;
 
}
 
@Entity
public class Employee {
 
    @ManyToOne
    @JoinColumn(name = "department_id")
    private Department department;
 
}

In the Department entity, we use the @OneToMany annotation to specify the relationship between the Department entity and the Employee entity. The mappedBy attribute specifies the name of the attribute in the Employee entity that owns the relationship. In this case, the Department entity doesn’t own the relationship, so we specify mappedBy = “department”.

In the Employee entity, we use the @ManyToOne annotation to specify the relationship between the Employee entity and the Department entity. The @JoinColumn annotation specifies the name of the foreign key column in the Employee table referencing the Department table.

3.2. Many-To-Many Bidirectional Association

When dealing with a many-to-many bidirectional association, it’s important to understand that each entity involved will have a collection of references to the other entity.

To illustrate this concept, let’s consider the example of a Student entity that has a collection of Course entities and a Course entity that in turn has a collection of Student entities. By establishing such a bidirectional association, we enable both entities to be aware of each other and make it easier to navigate and manage their relationship.

Here’s an example of how to create a many-to-many bidirectional association:

@Entity
public class Student {
 
    @ManyToMany(mappedBy = "students")
    private List<Course> courses;
 
}
 
@Entity
public class Course {
 
    @ManyToMany
    @JoinTable(name = "course_student",
        joinColumns = @JoinColumn(name = "course_id"),
        inverseJoinColumns = @JoinColumn(name = "student_id"))
    private List<Student> students;
 
}

In the Student entity, we use the @ManyToMany annotation to specify the relationship between the Student entity and the Course entity. The mappedBy attribute specifies the attribute’s name in the Course entity that owns the relationship. In this case, the Course entity owns the relationship, so we specify mappedBy = “students”.

In the Course entity, we use the @ManyToMany annotation to specify the relationship between the Course entity and the Student entity. The @JoinTable annotation specifies the name of the join table that stores the relationship.

4. Unidirectional vs. Bidirectional Association

Unidirectional and bidirectional associations in object-oriented programming differ in the direction of the relationship between the two classes.

Firstly, unidirectional associations only have a relationship in one direction, whereas bidirectional associations have a relationship in both directions. This difference can impact the design and functionality of software systems. For example, bidirectional associations can make it easier to navigate between related classes, but they can also introduce more complexity and potential for errors.

On the other hand, unidirectional associations can be simpler and less error-prone, but they may require more workarounds to navigate between related classes.

Overall, understanding the differences between unidirectional and bidirectional associations is crucial for making informed decisions about the design and implementation of software systems.

Here’s a table summarizing the differences between unidirectional and bidirectional associations in a database:

Unidirectional Association Bidirectional Association
Definition A relationship between two tables where one table has a foreign key that references the primary key of another table. A relationship between two tables where both tables have a foreign key that references the primary key of the other table.
Navigation Only navigable in one direction – from the child table to the parent table. Navigable in both directions – from either table to the other.
Performance Generally faster due to simpler table structure and fewer constraints. Generally slower due to additional constraints and table structure complexity.
Data Consistency Ensured by the foreign key constraint in the child table referencing the primary key in the parent table. Ensured by the foreign key constraint in the child table referencing the primary key in the parent table.
Flexibility Less flexible as changes in the child table may require changes to the parent table schema. More flexible as changes in either table can be made independently without affecting the other.

Notably, the specifics of implementation can vary depending on the database management system used. However, to provide a general understanding, the table above presents an overview of the differences between unidirectional and bidirectional associations.

It’s important to recognize these variations as they can significantly impact the performance and functionality of the database system.

5. Conclusion

In this article, we saw how the choice between unidirectional or bidirectional associations relies on the software’s specific demands. Unidirectional associations are simpler and may be sufficient for many applications, while bidirectional associations provide more flexibility and can be useful in more complex scenarios.

However, bidirectional associations can also introduce more complexity and potential issues, such as circular dependencies and memory leaks, and should be used with caution. It’s important to carefully consider the trade-offs and choose the appropriate type of association for each situation.

The code backing this article is available on GitHub. Once you're logged in as a Baeldung Pro Member, start learning and coding on the project.
Baeldung Pro – NPI EA (cat = Baeldung)
announcement - icon

Baeldung Pro comes with both absolutely No-Ads as well as finally with Dark Mode, for a clean learning experience:

>> Explore a clean Baeldung

Once the early-adopter seats are all used, the price will go up and stay at $33/year.

Partner – Microsoft – NPI EA (cat = Spring Boot)
announcement - icon

Azure Container Apps is a fully managed serverless container service that enables you to build and deploy modern, cloud-native Java applications and microservices at scale. It offers a simplified developer experience while providing the flexibility and portability of containers.

Of course, Azure Container Apps has really solid support for our ecosystem, from a number of build options, managed Java components, native metrics, dynamic logger, and quite a bit more.

To learn more about Java features on Azure Container Apps, visit the documentation page.

You can also ask questions and leave feedback on the Azure Container Apps GitHub page.

Partner – Orkes – NPI EA (cat = Spring)
announcement - icon

Modern software architecture is often broken. Slow delivery leads to missed opportunities, innovation is stalled due to architectural complexities, and engineering resources are exceedingly expensive.

Orkes is the leading workflow orchestration platform built to enable teams to transform the way they develop, connect, and deploy applications, microservices, AI agents, and more.

With Orkes Conductor managed through Orkes Cloud, developers can focus on building mission critical applications without worrying about infrastructure maintenance to meet goals and, simply put, taking new products live faster and reducing total cost of ownership.

Try a 14-Day Free Trial of Orkes Conductor today.

Partner – Orkes – NPI EA (tag = Microservices)
announcement - icon

Modern software architecture is often broken. Slow delivery leads to missed opportunities, innovation is stalled due to architectural complexities, and engineering resources are exceedingly expensive.

Orkes is the leading workflow orchestration platform built to enable teams to transform the way they develop, connect, and deploy applications, microservices, AI agents, and more.

With Orkes Conductor managed through Orkes Cloud, developers can focus on building mission critical applications without worrying about infrastructure maintenance to meet goals and, simply put, taking new products live faster and reducing total cost of ownership.

Try a 14-Day Free Trial of Orkes Conductor today.

eBook – HTTP Client – NPI EA (cat=HTTP Client-Side)
announcement - icon

The Apache HTTP Client is a very robust library, suitable for both simple and advanced use cases when testing HTTP endpoints. Check out our guide covering basic request and response handling, as well as security, cookies, timeouts, and more:

>> Download the eBook

eBook – Java Concurrency – NPI EA (cat=Java Concurrency)
announcement - icon

Handling concurrency in an application can be a tricky process with many potential pitfalls. A solid grasp of the fundamentals will go a long way to help minimize these issues.

Get started with understanding multi-threaded applications with our Java Concurrency guide:

>> Download the eBook

eBook – Java Streams – NPI EA (cat=Java Streams)
announcement - icon

Since its introduction in Java 8, the Stream API has become a staple of Java development. The basic operations like iterating, filtering, mapping sequences of elements are deceptively simple to use.

But these can also be overused and fall into some common pitfalls.

To get a better understanding on how Streams work and how to combine them with other language features, check out our guide to Java Streams:

>> Join Pro and download the eBook

eBook – Persistence – NPI EA (cat=Persistence)
announcement - icon

Working on getting your persistence layer right with Spring?

Explore the eBook

Course – LS – NPI EA (cat=REST)

announcement - icon

Get started with Spring Boot and with core Spring, through the Learn Spring course:

>> CHECK OUT THE COURSE

Course – Spring Sale 2025 – NPI EA (cat= Baeldung)
announcement - icon

Yes, we're now running our Spring Sale. All Courses are 25% off until 26th May, 2025:

>> EXPLORE ACCESS NOW

Course – Spring Sale 2025 – NPI (All)
announcement - icon

Yes, we're now running our Spring Sale. All Courses are 25% off until 26th May, 2025:

>> EXPLORE ACCESS NOW

Course – LSD – NPI (cat=JPA)
announcement - icon

Get started with Spring Data JPA through the reference Learn Spring Data JPA:

>> CHECK OUT THE COURSE

eBook Jackson – NPI EA – 3 (cat = Jackson)
2 Comments
Oldest
Newest
Inline Feedbacks
View all comments