Reputation: 21320
I have a question related to lazy loading of OneToOne
association mapping.
Case 1 Foreign key is in Child table (Address)
@Entity
public class User {
..........
@OneToOne(mappedBy="user")
private Address address;
@Entity
public class Address{
.........
@OneToOne
@JoinColumn(name = "user_id")
private User user;
In the above Address lazy loading doesn't work.
Case 2 Foreign key is in Parent table (User)
@Entity
public class User {
.............
@OneToOne(fetch = FetchType.LAZY)
@JoinColumn(name="address_id")
private Address address;
@Entity
public class Address {
........
@OneToOne(mappedBy="address")
private User user;
In the above Address lazy loading works.
Could please someone explain me why One to one
lazy loading doesn't work in first case but works in second?
Upvotes: 0
Views: 5450
Reputation: 4429
I haven't been able to make it work, so I wound up using a prepared statement where I JOIN FETCH
the things that Hibernate was querying for after-the-fact anyhow.
Adding optional=true
or faking a OneToMany
relationship are, IMO, wrong ways to fix this.
Upvotes: 1
Reputation: 9162
@OneToOne
is a bit tricky to handle.
It all depends on what persistence provider you're using.
Some providers do not respect FetchType.LAZY
hint.
You can try to specify (on both ends of relation)
@OneToOne(optional = true, fetch = FetchType.LAZY)
To understand what happens here lets take a look at the level:
first case:
+-----------------+ +------------------+
| USER | | Address |
| |1 1| |
| +-------------+ USER_ID (FK) |
| | | |
| | | |
+-----------------+ +------------------+
When you load the user Hibernate has to know if the Address is present or not.
So Hibernate issues a SQL request similar to this:
SELECT * FROM USER WHERE ID = ?
SELECT * FROM ADDRESS WHERE user_id = ?
When getting the result the entity is already loaded, so it's no point to assign a LazyProxy to the Address. Hibernate assigns the fetched object.
Second case:
+-----------------+ +------------------+
| USER | | Address |
| |1 1| |
| ADDRESS_ID +-------------+ |
| | | |
| | | |
+-----------------+ +------------------+
SELECT * FROM USER WHERE ID = ?
Hibernate does not need to check if the Address is there or not. That's why the proxy is created.
Upvotes: 4
Reputation: 8606
Read this article. It will give you understanding why one to one on inverse side (mapped by) attribute does not work as expected.One to One Lazy explanation.
Actually on inverse side hibernate needs to know what is the value of mapping, because user can ask for value immediately.
Read the article and you will get clear understanding how things work.
Thanks
Upvotes: 0