Hibernate Tutorial
Core Hibernate
Hibernate Mapping
Hibernate Annotations
Hibernate with Spring Framework
Hibernate with Database
Hibernate Log4j
Inheritance Mapping
In a one-to-one relationship, one record in a table corresponds to one and only one record in another table. For instance, consider the relationship between a User
and a UserProfile
- each user has only one profile, and each profile belongs to only one user.
In this tutorial, we will learn how to implement a one-to-one mapping using Hibernate.
First, ensure you have Hibernate's dependencies in your project. If you're using Maven, this primarily means including hibernate-core
.
user
table: To store user details.user_profile
table: To store user profile details. It will have a foreign key (user_id
) referring to the user
table.@Entity @Table(name="user") public class User { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name="id") private int id; @Column(name="username") private String username; @OneToOne(cascade=CascadeType.ALL) @JoinColumn(name="profile_id") private UserProfile profile; // constructors, getters, setters... }
@Entity @Table(name="user_profile") public class UserProfile { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name="id") private int id; @Column(name="bio") private String bio; @OneToOne(mappedBy="profile", cascade=CascadeType.ALL) private User user; // constructors, getters, setters... }
@OneToOne
: Specifies that this is a one-to-one relationship.@JoinColumn
: Specifies the foreign key column for the relationship.mappedBy
: Refers to the property name of the association on the owner side. In our case, the User
entity owns the relationship.Session session = sessionFactory.getCurrentSession(); session.beginTransaction(); // create a user and a profile User tempUser = new User("john_doe"); UserProfile tempProfile = new UserProfile("A passionate developer."); // associate them tempUser.setProfile(tempProfile); tempProfile.setUser(tempUser); // save the user (due to CascadeType.ALL, this will also save the profile) session.save(tempUser); session.getTransaction().commit();
Session session = sessionFactory.getCurrentSession(); session.beginTransaction(); // fetch user with id=1 User tempUser = session.get(User.class, 1); // print the user and his/her profile System.out.println(tempUser.getUsername()); System.out.println(tempUser.getProfile().getBio()); session.getTransaction().commit();
By default, one-to-one relationships in Hibernate are eagerly fetched:
User
, the associated UserProfile
is automatically fetched too.However, you can change the fetching strategy if needed using the fetch
attribute of the @OneToOne
annotation:
@OneToOne(fetch=FetchType.LAZY, cascade=CascadeType.ALL) @JoinColumn(name="profile_id") private UserProfile profile;
Mapping one-to-one relationships in Hibernate is straightforward, but you must ensure that your database schema supports the relationship. Always be cautious about the fetch type, as it can have performance implications, especially if you're working with large datasets.
Hibernate one-to-one mapping example:
@OneToOne
annotation.// In the parent entity (Person) @OneToOne(mappedBy = "person", cascade = CascadeType.ALL, fetch = FetchType.LAZY) private Address address;
// In the child entity (Address) @OneToOne @JoinColumn(name = "person_id", unique = true) private Person person;
Configuring one-to-one associations in Hibernate:
@OneToOne
annotation.@JoinColumn
to define the foreign key column.@OneToOne @JoinColumn(name = "address_id") private Address address;
Mapping one-to-one relationships with Hibernate annotations:
@OneToOne
annotation on the reference variable in the parent entity.@OneToOne(mappedBy = "person") private Address address;
Lazy loading with Hibernate one-to-one mapping:
fetch = FetchType.LAZY
to enable lazy loading.@OneToOne(mappedBy = "person", fetch = FetchType.LAZY) private Address address;
Bidirectional one-to-one mapping in Hibernate:
@OneToOne
and @JoinColumn
in both entities.// In the parent entity (Person) @OneToOne(mappedBy = "person", cascade = CascadeType.ALL, fetch = FetchType.LAZY) private Address address;
// In the child entity (Address) @OneToOne @JoinColumn(name = "person_id", unique = true) private Person person;
Cascading operations in Hibernate one-to-one mapping:
cascade
attribute in the @OneToOne
annotation.@OneToOne(mappedBy = "person", cascade = CascadeType.ALL, fetch = FetchType.LAZY) private Address address;
Fetching strategies in Hibernate one-to-one associations:
select
, join
, subselect
.fetch
attribute.@OneToOne(mappedBy = "person", fetch = FetchType.LAZY) private Address address;
HQL queries for one-to-one associations in Hibernate:
String hql = "FROM Person p JOIN FETCH p.address WHERE p.id = :personId"; Query query = session.createQuery(hql); query.setParameter("personId", 1L); Person person = (Person) query.uniqueResult();
Handling orphan removal with Hibernate one-to-one mapping:
orphanRemoval = true
in the @OneToOne
annotation.@OneToOne(mappedBy = "person", cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.LAZY) private Address address;