Java.Hibernate.Beginner.OneToOne.Bidirectional

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.

This entry was posted in Без рубрики. Bookmark the permalink.