Lazy Initialization Problem With Hibernate One-To-One Mapping

There are different ways for lazy initialisation in Hibernate. One of the common practices is:

public class Student {
    @OneToMany(fetch = FetchType.LAZY)
    private List<Book> books;

    @OneToOne(fetch = FetchType.LAZY)
    private Address address;
}

public class Book {
    @ManyToOne(fetch = FetchType.LAZY)
    private Student student;
}

So, what happens with this lazy initialisation? Lets look in deep one by one.

@OneToMany

Considering the above example when Student is loaded from DB a proxy of empty Book list is returned instead of book list. It is only loaded when the Book list is accessed.

@ManyToOne

In case of ManyToOne, when Book is loaded from DB, hibernate checks the foreign key. If the foreign key is not null a proxy is injected instead of Student from DB.

@OneToOne

The lazy initialisation doesn’t work with above OneToOne mapping example. The reason is when hibernate loads Student it doesn’t know whether Address should be injected by proxy or keep it null.

The bytecode instrumentation (compile time instrumentation) is the solution for this.

Another solution is to make it required as:

@OneToOne(fetch = FetchType.LAZY, optional = false)

When it constrained, the hibernate can easily inject a proxy. So, lazy initialisation works fine. But the issue arise when it doesn’t fit with business requirement. Therefore we must find another way to keep it lazy.

Another hackish way is making it a @OneToMany relationship and then hibernate can inject a proxy of empty list.

Or you can keep foreign key in both side of the one-to-one relation.

Be lazy, be happy… 🙂

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s