✅ 1) What does a one-to-one relationship look like in the database?
- There’s one table for each entity, e.g.:
users
table with primary keyid
.user_profile
table with primary keyid
and a foreign key column pointing back tousers.id
.
🔹 Schema example (using UserProfile owning the relationship):
CREATE TABLE users (
id BIGINT PRIMARY KEY AUTO_INCREMENT,
username VARCHAR(255) NOT NULL
);
CREATE TABLE user_profile (
id BIGINT PRIMARY KEY AUTO_INCREMENT,
address VARCHAR(255),
user_id BIGINT UNIQUE, -- unique foreign key to enforce 1-1
CONSTRAINT fk_user_profile_user
FOREIGN KEY (user_id) REFERENCES users(id)
);
✅ The UNIQUE
constraint on user_profile.user_id
enforces one-to-one: a profile cannot be shared by multiple users.
🔹 How it links:
- Each row in
user_profile
has a uniqueuser_id
pointing to one row inusers
.
✅ 2) Does calling profile.getUser()
generate additional SQL?
Yes, it depends on the fetch type you configure:
🔹 EAGER fetching (default for @OneToOne)
@OneToOne
@JoinColumn(name = "user_id")
private User user;
When you load UserProfile
, Hibernate immediately joins or separately fetches the User → so calling profile.getUser()
later does not trigger a new SQL, because the User is already loaded.
🔹 LAZY fetching (explicitly set)
@OneToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "user_id")
private User user;
When you load UserProfile
, Hibernate does not load the associated User yet.
Calling profile.getUser()
for the first time will trigger a separate SQL query like:
select ... from users where id = ?
This is called lazy loading — it defers loading until you actually access the relationship.
🔹 Example SQL behavior with LAZY:
UserProfile profile = session.get(UserProfile.class, 1L); // loads profile only
// No query for user yet
User user = profile.getUser(); // triggers separate SQL here to fetch User
🔹 Hibernate-generated SQL with LAZY fetch:
1️⃣ Initial load:
select ... from user_profile where id = 1;
2️⃣ When accessing profile.getUser():
select ... from users where id = ?;
✅ Key takeaway:
- In the database, a one-to-one relationship is typically implemented with a foreign key + unique constraint to enforce exclusivity.
- Whether
profile.getUser()
triggers an additional SQL depends entirely on yourfetch
type:EAGER
→ loads with the owning entity, no extra SQL later.LAZY
→ loads only when you access the related entity, generating an additional SQL at that moment.