Hibernate one-to-one mapping using annotations
If you are working on any hibernate project or you are planning to work on any in future, then you can easily understand the one-to-one relationships between several entities in your application. In this post, i will discuss variations of one-to-one mappings supported in hibernate.
Download source code
Lets see them in action one by one:
Table structure will be like this:
To make such association, refer the account entity in EmployeeEntity class as follow:
The join column is declared with the
@JoinColumn annotation which looks like the @Column annotation. It has one more parameters named referencedColumnName. This parameter declares the column in the targeted entity that will be used to the join.
If no @JoinColumn is declared on the owner side, the defaults apply. A join column(s) will be created in the owner table and its name will be the concatenation of the name of the relationship in the owner side, _ (underscore), and the name of the primary key column(s) in the owned side.
In a bidirectional relationship, one of the sides (and only one) has to be the owner: the owner is responsible for the association column(s) update. To declare a side as not responsible for the relationship, the attribute mappedBy is used. mappedBy refers to the property name of the association on the owner side.
Above “mappedBy” attribute declares that it is dependent on owner entity for mapping.
Lets test above mappings in running code:
Running above code creates desired schema in database and run these SQL queries.Download source code
Sections in this post: Various supported techniques Using foreign key association Using a common join table Using shared primary keyFor this article, I am extending the example written for hello world example. We have two entities here: Employee and Account.
Various supported techniques
In hibernate there are 3 ways to create one-to-one relationships between two entities. Either way you have to use @OneToOne annotation. First technique is most widely used and uses a foreign key column in one to table. Second technique uses a rather known solution of having a third table to store mapping between first two tables. Third technique is something new which uses a common primary key value in both the tables.Lets see them in action one by one:
Using foreign key association
In this association, a foreign key column is created in owner entity. For example, if we make EmployeeEntity owner, then a extra column “ACCOUNT_ID” will be created in Employee table. This column will store the foreign key for Account table.Table structure will be like this:
To make such association, refer the account entity in EmployeeEntity class as follow:
1.
@OneToOne
2.
@JoinColumn
(name=
"ACCOUNT_ID"
)
3.
private
AccountEntity account;
If no @JoinColumn is declared on the owner side, the defaults apply. A join column(s) will be created in the owner table and its name will be the concatenation of the name of the relationship in the owner side, _ (underscore), and the name of the primary key column(s) in the owned side.
In a bidirectional relationship, one of the sides (and only one) has to be the owner: the owner is responsible for the association column(s) update. To declare a side as not responsible for the relationship, the attribute mappedBy is used. mappedBy refers to the property name of the association on the owner side.
1.
@OneToOne
(mappedBy=
"account"
)
2.
private
EmployeeEntity employee;
Lets test above mappings in running code:
01.public class TestForeignKeyAssociation {
03. public static void main(String[] args) {
04. Session session = HibernateUtil.getSessionFactory().openSession();
05. session.beginTransaction();
06.
07. AccountEntity account = new AccountEntity();
08. account.setAccountNumber("123-345-65454");
09.
10. // Add new Employee object
11. EmployeeEntity emp = new EmployeeEntity();
12. emp.setEmail("demo-user@mail.com");
13. emp.setFirstName("demo");
14. emp.setLastName("user");
15.
16. // Save Account
17. session.saveOrUpdate(account);
18. // Save Employee
19. emp.setAccount(account);
20. session.saveOrUpdate(emp);
21.
22. session.getTransaction().commit();
23. HibernateUtil.shutdown();
24. }
25.}
1.
Hibernate:
insert
into
ACCOUNT (ACC_NUMBER)
values
(?)
2.
Hibernate:
insert
into
Employee (ACCOUNT_ID, EMAIL, FIRST_NAME, LAST_NAME)
values
(?, ?, ?, ?)
Using a common join table
This approach is not new to all of us. Lets start with targeted DB structure in this technique.In this technique, main annotation to be used is @JoinTable. This annotation is used to define the new table name (mandatory) and foreign keys from both of the tables. Lets see how it is used:
1.
@OneToOne
(cascade = CascadeType.ALL)
2.
@JoinTable
(name=
"EMPLOYEE_ACCCOUNT"
, joinColumns =
@JoinColumn
(name=
"EMPLOYEE_ID"
),
3.
inverseJoinColumns =
@JoinColumn
(name=
"ACCOUNT_ID"
))
4.
private
AccountEntity account;
Testing above entities generates following SQL queries in log files:
1.
Hibernate:
insert
into
ACCOUNT (ACC_NUMBER)
values
(?)
2.
Hibernate:
insert
into
Employee (EMAIL, FIRST_NAME, LAST_NAME)
values
(?, ?, ?)
3.
Hibernate:
insert
into
EMPLOYEE_ACCCOUNT (ACCOUNT_ID, EMPLOYEE_ID)
values
(?, ?)
Using shared primary key
In this technique, hibernate will ensure that it will use a common primary key value in both the tables. This way primary key of EmployeeEntity can safely be assumed the primary key of AccountEntity also.Table structure will be like this:
In this approach, @PrimaryKeyJoinColumn is the main annotation to be used.Let see how to use it.
1.
@OneToOne
(cascade = CascadeType.ALL)
2.
@PrimaryKeyJoinColumn
3.
private
AccountEntity account;
1.
@OneToOne
(mappedBy=
"account"
, cascade=CascadeType.ALL)
2.
private
EmployeeEntity employee;
1.
Hibernate:
insert
into
ACCOUNT (ACC_NUMBER)
values
(?)
2.
Hibernate:
insert
into
Employee (ACCOUNT_ID, EMAIL, FIRST_NAME, LAST_NAME)
values
(?, ?, ?, ?)
Happy Learning !!
Download source code
Source: http://howtodoinjava.com/2012/11/15/hibernate-one-to-one-mapping-using-annotations/
No comments:
Post a Comment