I’m happy, that finally we have a complete tutorial that addresses the challenges faced by many programmers. Entity relationships(@OneToMany and @ManyToOne). So everything about relationships in covered here. Use the links to quickly jump to any section you want.
We explain the concept, then we implement it.
- Part 1 – Introduction
- Part 2 – Setting Up
- Part 3 – @ManyToOne
- Part 4 – Configuring H2 Database
- Part 5 – Database Initialization(data.sql)
- Part 6 – @OneToMany
- Part 7 – mappedBy Attribute
- Part 8 to 12 – Infinite Recursion, @JoinColumn, JsonManagedReference etc
- Part 13 to 16 – Retrieving Child Records
- Part 17 to 20 – Inserting New Records. Using REST Client
- Part 21 to 28 – Deleting, CascadeTypes and FetchTypes
Part 1 – Introduction
In this comprehensive tutorial, we’ll build an application made up of three entities: Location, User and Post.
How they relate is that: Location contains users and User has posts. This is illustrated in the figure below
Part 2 – Setting Up the Application
In this part, we would set up a Spring Boot Starter application. Follow the steps below:
Step 1: Create a Spring application (you should be able to do this by now). Add the starter web dependency. Also add the starter-jpa dependency.
Step 2: Create three classes corresponding to Post, User and Location. Put them in the models package
Step 3: Also create all the repositories in the repositories package
Step 4: Create the services in the Services package
Step 5: Finally, create the RestControllers in the controllers package
Part 3 – @ManyToOne Relationship
We would now configure Many-to-one relationship between the User and the Location entities. Similarly, we do the same between the Post and User entities.
Follow the steps below:
Step 1: Annotate the Location field of the User entity with @ManyToOne annotation.
Step 2: Annotate the User field of the Post entity with @ManyToOne annotation
When you use these annotation, the entity decides to handle the relationship. In the first case, the User entity does this by creating a column called location_id in the User table. Similarly, the Post entity does this by creating a column called user_id
Part 4 – Configure the H2 Database
H2 Database is an in-memory database that is normally used during development. Now we configure the H2 database following the steps below:
Step 1: Open the application.properties file. It is in the src/main/resources folder
Step 2: Add the following code in the application.properties file
spring.h2.console.enabled=true spring.datasource.platform=h2 spring.datasource.url=jdbc:h2:mem:socialdb spring.datasource.driverClassName=org.h2.Driver
Step 3: Run the the application and access the H2 Console
Part 5 – Database Initialization (data.sql)
We would write a script to insert some initial data into the database. Follow the steps below:
Step 1: Create a file inside the src/main/resources folder. Name it data.sql
Step 2: Open the file and add the following code
insert into Location(id, name) values(1, 'Budapest, Hungary'); insert into Location(id, name) values(2, 'Owerri, Nigeria'); insert into Location(id, name) values(3, 'Califonia, USA'); insert into User(id, firstname, lastname, email, location_id) values(1, 'Kindson', 'Munonye', 'firstname.lastname@example.org', 1); insert into User(id, firstname, lastname, email, location_id) values(2, 'Jeffrey', 'Yuba', 'email@example.com', 2); insert into User(id, firstname, lastname, email, location_id) values(3, 'Solace', 'Okeke', 'firstname.lastname@example.org', 3); insert into Post(id, post_date, details, user_id) values(1, CURRENT_TIMESTAMP(), 'Very good post', 1); insert into Post(id, post_date, details, user_id) values(2, CURRENT_TIMESTAMP(), 'A rainy day', 2); insert into Post(id, post_date, details, user_id) values(3, CURRENT_TIMESTAMP(), 'nice tutorials', 3);
Step 3: Run the application. Access h2-console and verify that the data is inserted. The H2-Console window is shown below
Part 6 – @OneToMany Relationship
This relationship allows us to get list of child entities under a parent entity. For examples, we could get the list of posts for a user. Or we could get list of users in a location. Follow the steps below:
Step 1: In the Location class, add a private field of List<User> type. (This means list of all users under that location)
Step 2: Annotate this field with the @OneToMany annotation
Step 3: In the User class, add a private field of List<Post> type. (This means list of all posts for that user)
Step 4: Annotate this field with the @OneToMany annotation
Step 5: Run the application and access the H2 Console
Now, you will notice in the H2 console that there are additional tables that have been created.
What happens here is this:
for the User-Location relationship, the Location entity decides to handle the relationship mapping by creating an additional table called LOCATION_USERS.
Again, for the Post-User relationship, the User entify decides the handle the relationship by creating an additional table called POST_USERS.
But remember that the relationship mapping has already been handled using by the @ManyToOne using the location_id and the user_id columns.
This duplicate mapping can be resolved using the mappedBy attibute
Part 7 – The mappedBy Attribute
The mappedBy is an attribute of the @OneToMany relationship. You use the mappedBy to tell the @OneToMany annotation that the relationship has already been handled using a foreign key in the corresponding entity. In this way, an additional table is not created.
To do this:
Step 1: In the @OneToMany annotation in the Location entity, add mappedBy=”location”
Step 2: In the @OneToMany annotation in the User entity, add mappedBy=”user”
Step 3: Launch the application, access H2-Console and check that there are no more duplicate tables;
Let’s now move on the the next section…