Hibernate one to many mapping is made between two entities where the first entity can have a relation with multiple instances of the second entity but the second can be associated with only one instance of the first entity. It is a 1 to N relationship.
For example, in any company, an employee can register for multiple bank accounts but one bank account will be associated with one and only one employee. In this hibernate one to many mapping annotation examples, we will learn to make such mappings in the database using hibernate.
1. Design Overview
We should use one to many mapping to create 1..N relationship between entities or objects.
For example, as discussed above, we have to write two entities i.e. EmployeeEntity
and AccountEntity
such that multiple accounts can be associated with a single employee, but one single account can not be shared between two or more employees.
This problem can be solved in two different ways.
- One is to have a foreign key column in the ACCOUNT table i.e.
EMPLOYEE_ID
. This column will refer to the primary key ofEmployee
table. This way no two accounts can be associated with multiple employees. Obviously, the account number needs to be unique for enforcing this restriction. - The second approach is to have a link table. Let’s say the table name is
EMPLOYEE_ACCOUNT
. This table will have two columns i.e.EMP_ID
that will be a foreign key referring to the primary key inEMPLOYEE
table and similarlyACCOUNT_ID
which will be a foreign key referring to the primary key ofACCOUNT
table.
2. Using Foreign Key Association
We are designing a unidirectional relationship where when we delete an employee then account are deleted as well. But when we delete an account (one of many) then employee is unaffected.
2.1. Create Association
Let’s first see the schema design.

Then we write the entity classes.
@Entity
@Table(name = "EMPLOYEE")
public class EmployeeEntity implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "ID")
private Integer employeeId;
@OneToMany(cascade=CascadeType.ALL)
@JoinColumn(name="EMPLOYEE_ID")
private Set<AccountEntity> accounts;
//Other fields, getters, setters are hidden for brevity
}
@Entity
@Table(name = "ACCOUNT")
public class AccountEntity implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "ID")
private Integer accountId;
//Other fields, getters, setters are hidden for brevity
}
2.2. Demo
Let’s test the relationship and monitor the CREATE queries.
create table Employee (
ID integer generated by default as identity,
EMAIL varchar(100) not null,
FIRST_NAME varchar(100) not null,
LAST_NAME varchar(100) not null,
primary key (ID)
)
create table ACCOUNT (
ID integer generated by default as identity,
ACC_NUMBER varchar(100) not null,
EMPLOYEE_ID integer,
primary key (ID)
)
alter table if exists ACCOUNT
add constraint FKmyqrmihkv5isa3tjsj01x65sr
foreign key (EMPLOYEE_ID)
references Employee
AccountEntity account1 = new AccountEntity();
account1.setAccountNumber("Account detail 1");
AccountEntity account2 = new AccountEntity();
account2.setAccountNumber("Account detail 2");
AccountEntity account3 = new AccountEntity();
account3.setAccountNumber("Account detail 3");
//Add new Employee object
EmployeeEntity employee = new EmployeeEntity();
employee.setEmail("demo-user-first@mail.com");
employee.setFirstName("demo-one");
employee.setLastName("user-one");
Set<AccountEntity> accountList = new HashSet<AccountEntity>();
accountList.add(account1);
accountList.add(account2);
accountList.add(account3);
employee.setAccounts(accountList);
//Save Employee
session.persist(employee);
Program Output:
Hibernate: insert into Employee (ID, EMAIL, FIRST_NAME, LAST_NAME) values (default, ?, ?, ?)
Hibernate: insert into ACCOUNT (ID, ACC_NUMBER) values (default, ?)
Hibernate: insert into ACCOUNT (ID, ACC_NUMBER) values (default, ?)
Hibernate: insert into ACCOUNT (ID, ACC_NUMBER) values (default, ?)
Hibernate: update ACCOUNT set EMPLOYEE_ID=? where ID=?
Hibernate: update ACCOUNT set EMPLOYEE_ID=? where ID=?
Hibernate: update ACCOUNT set EMPLOYEE_ID=? where ID=?
3. Using Link Table
This approach uses the @JoinTable annotation to create a link table that stores the associations between account and employee entities.
3.1. Create Association
Lets see how the database schema will look like:

On EmployeeEntity, we will add the @OneToMany annotation along with @JoinTable definition. This is the owning side.
@Entity
@Table(name = "EMPLOYEE")
public class EmployeeEntity implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "ID")
private Integer employeeId;
@OneToMany(cascade = CascadeType.ALL, orphanRemoval = true)
@JoinTable(name = "EMPLOYEE_ACCOUNT",
joinColumns = {@JoinColumn(name = "EMPLOYEE_ID", referencedColumnName = "ID")},
inverseJoinColumns = {@JoinColumn(name = "ACCOUNT_ID", referencedColumnName = "ID")})
private Set<AccountEntity> accounts;
//Other fields, getters, setters are hidden for brevity
}
If we want to create a bi-directional relationship then we need to use @ManyToOne
association on the child side.
@Entity
@Table(name = "EMPLOYEE")
public class EmployeeEntity implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "ID")
private Integer employeeId;
@OneToMany(mappedBy = "employee", cascade = CascadeType.ALL, orphanRemoval = true)
@JoinTable(name = "EMPLOYEE_ACCOUNT",
joinColumns = {@JoinColumn(name = "EMPLOYEE_ID", referencedColumnName = "ID")},
inverseJoinColumns = {@JoinColumn(name = "ACCOUNT_ID", referencedColumnName = "ID")})
private Set<AccountEntity> accounts;
//Other fields, getters, setters are hidden for brevity
}
@Entity
@Table(name = "ACCOUNT")
public class AccountEntity implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "ID")
private Integer accountId;
@ManyToOne
private EmployeeEntity employee;
//Other fields, getters, setters are hidden for brevity
}
3.2. Demo
Now, it’s time to test the code. I have written the following code to test the above entities.
AccountEntity account1 = new AccountEntity();
account1.setAccountNumber("123-345-65454");
AccountEntity account2 = new AccountEntity();
account2.setAccountNumber("123-345-6542222");
//Add new Employee object
EmployeeEntity emp = new EmployeeEntity();
emp.setEmail("demo-user@mail.com");
emp.setFirstName("demo");
emp.setLastName("user");
Set<AccountEntity> accounts = new HashSet<>();
accounts.add(account1);
accounts.add(account2);
emp.setAccounts(accounts);
//Save Employee
session.persist(emp);
Program Output:
Hibernate: insert into Employee (EMAIL, FIRST_NAME, LAST_NAME, ID) values (?, ?, ?, ?)
Hibernate: insert into ACCOUNT (ACC_NUMBER, ID) values (?, ?)
Hibernate: insert into ACCOUNT (ACC_NUMBER, ID) values (?, ?)
Hibernate: insert into EMPLOYEE_ACCOUNT (EMPLOYEE_ID, ACCOUNT_ID) values (?, ?)
Hibernate: insert into EMPLOYEE_ACCOUNT (EMPLOYEE_ID, ACCOUNT_ID) values (?, ?)
In this hibernate @OneToMany mapping annotation example using list, we learned to create 1..N
relationships between two entities using foreign key association and join table techniques.
Happy Learning !!
Comments