A User
entity has exactly one UserProfile
, and each UserProfile
belongs to exactly one User
.
🔹 Entity 1: User
import javax.persistence.*;
@Entity
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String username;
@OneToOne(mappedBy = "user", cascade = CascadeType.ALL)
private UserProfile profile;
// Getters and setters
public Long getId() { return id; }
public String getUsername() { return username; }
public void setUsername(String username) { this.username = username; }
public UserProfile getProfile() { return profile; }
public void setProfile(UserProfile profile) { this.profile = profile; }
}
🔹 Entity 2: UserProfile
import javax.persistence.*;
@Entity
public class UserProfile {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String address;
@OneToOne
@JoinColumn(name = "user_id") // foreign key column in user_profile table
private User user;
// Getters and setters
public Long getId() { return id; }
public String getAddress() { return address; }
public void setAddress(String address) { this.address = address; }
public User getUser() { return user; }
public void setUser(User user) { this.user = user; }
}
🔹 What happens here:
✅ The UserProfile
table has a foreign key column user_id
referencing users.id
.
✅ UserProfile
owns the relationship because it has the @JoinColumn
.
✅ In User
, the @OneToOne(mappedBy = "user")
points back to the user
field in UserProfile
→ this makes UserProfile
the owner and User
the inverse side.
🔹 How to create and persist both sides:
Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
User user = new User();
user.setUsername("alice");
UserProfile profile = new UserProfile();
profile.setAddress("123 Wonderland");
// Tie both sides of the bidirectional relationship
user.setProfile(profile);
profile.setUser(user);
session.persist(user); // cascade=ALL will persist UserProfile too
tx.commit();
session.close();
🔹 Important:
✅ Always set both sides of the bidirectional relationship (user.setProfile(profile)
and profile.setUser(user)
) to keep the in-memory model consistent.
✅ With cascade = CascadeType.ALL
on User.profile
, saving the User
also saves the UserProfile
.
✅ Key takeaway:
This example shows a bidirectional one-to-one where both User
and UserProfile
know each other → you can navigate in both directions in your domain model, and the database enforces the relationship via the foreign key.