π 1οΈβ£ Unidirectional @OneToOne Relationship
β
 In a unidirectional @OneToOne, only one entity knows about the other, and the foreign key is stored in the owning entity.
  
  
  π Example: A User has a Profile
- A User has exactly one Profile.
- A Profile belongs to exactly one User.
- The foreign key (profile_id) is stored in theUsertable.
  
  
  πΉ Step 1: Define the Owning Side (@OneToOne with @JoinColumn)
@Entity
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String username;
    @OneToOne
    @JoinColumn(name = "profile_id") // β
 Foreign key stored in User table
    private Profile profile;
}
- 
@JoinColumn(name = "profile_id")ensures that theUsertable stores the foreign key.
  
  
  πΉ Step 2: Define the Profile Entity (No Reference Back)
@Entity
public class Profile {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String bio;
}
- 
Profiledoes not referenceUser(unidirectional).
- 
Userowns the relationship and has theprofile_idcolumn.
πΉ Generated SQL
CREATE TABLE user (
    id BIGINT AUTO_INCREMENT PRIMARY KEY,
    username VARCHAR(255),
    profile_id BIGINT UNIQUE, -- β
 Foreign key stored here
    FOREIGN KEY (profile_id) REFERENCES profile(id)
);
CREATE TABLE profile (
    id BIGINT AUTO_INCREMENT PRIMARY KEY,
    bio VARCHAR(255)
);
β
 The profile_id foreign key is stored in User, ensuring a one-to-one relationship.
π Saving Data in Hibernate
Profile profile = new Profile();
profile.setBio("Software Engineer");
User user = new User();
user.setUsername("JohnDoe");
user.setProfile(profile); // β
 Link profile to user
entityManager.persist(profile); // β
 Save Profile first
entityManager.persist(user); // β
 Then save User
π Now the User is linked to the Profile.
π Querying Data
User user = entityManager.find(User.class, 1L);
System.out.println(user.getProfile().getBio()); // β
 Works!
β
 You can access the Profile from User, but not the other way around.
  
  
  π 2οΈβ£ Bidirectional @OneToOne Relationship
β
 In a bidirectional @OneToOne, both entities know about each other.
  
  
  π Example: A User has a Profile, and a Profile belongs to a User
- 
User owns the relationship (@OneToOnewith@JoinColumn).
- 
Profile has a reference back to User (@OneToOne(mappedBy = "profile")).
  
  
  πΉ Step 1: Define the Owning Side (@OneToOne with @JoinColumn)
@Entity
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String username;
    @OneToOne
    @JoinColumn(name = "profile_id") // β
 Foreign key stored in User
    private Profile profile;
}
β
 User owns the relationship and has the foreign key.
  
  
  πΉ Step 2: Define the Inverse Side (@OneToOne(mappedBy = "profile"))
@Entity
public class Profile {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String bio;
    @OneToOne(mappedBy = "profile") // β
 Inverse side
    private User user;
}
β
 mappedBy = "profile" tells Hibernate:
- "The foreign key is already in the Usertable."
- "Don't create another column in Profile."
πΉ Generated SQL
CREATE TABLE user (
    id BIGINT AUTO_INCREMENT PRIMARY KEY,
    username VARCHAR(255),
    profile_id BIGINT UNIQUE, -- β
 Foreign key stored here
    FOREIGN KEY (profile_id) REFERENCES profile(id)
);
CREATE TABLE profile (
    id BIGINT AUTO_INCREMENT PRIMARY KEY,
    bio VARCHAR(255)
);
β
 The foreign key is only in User.profile_id, keeping the relationship correct.
π Saving Data in Hibernate
Profile profile = new Profile();
profile.setBio("Software Engineer");
User user = new User();
user.setUsername("JohnDoe");
user.setProfile(profile);
profile.setUser(user); // β
 Set reference back
entityManager.persist(profile); // β
 Save Profile first
entityManager.persist(user); // β
 Then save User
π Now, both User and Profile reference each other.
π Querying Both Directions
β User β Profile
User user = entityManager.find(User.class, 1L);
System.out.println(user.getProfile().getBio()); // β
 Works!
β Profile β User
Profile profile = entityManager.find(Profile.class, 1L);
System.out.println(profile.getUser().getUsername()); // β
 Works!
β Unlike the unidirectional version, now you can access both User β Profile and Profile β User.
  
  
  π 3οΈβ£ Summary: Unidirectional vs. Bidirectional @OneToOne
| Feature | Unidirectional ( @OneToOne) | Bidirectional ( @OneToOne+mappedBy) | 
|---|---|---|
| @OneToOneused? | β Yes | β Yes (Both Sides) | 
| @JoinColumnused? | β Yes (Owning Side) | β Yes (Owning Side) | 
| mappedByused? | β No | β Yes (Inverse Side) | 
| Foreign key location? | In owning entity's table | In owning entity's table | 
| Reference back? | β No | β Yes (Both Can Access Each Other) | 
β
 Best Practice: Use bidirectional @OneToOne if you need to query from both entities.
π Unidirectional @OneToOne is simpler if you only query in one direction.
π― Final Takeaways
- 
Unidirectional @OneToOne= Only one entity knows about the other (@JoinColumnin the owning side).
- 
Bidirectional @OneToOne= Both entities reference each other (mappedByused on the inverse side).
- Always place the foreign key on the entity that owns the relationship.
- Use bidirectional if you need to query both ways.
 

 
    
Top comments (0)