Farouk Alhassan
Farouk Alhassan

Reputation: 3808

Hibernate lazy loading not working

I'm using version 3.6.1.Final

I have the following property in my entity bean

    @JoinColumn( name = "FOLDER_PARENT_ID", referencedColumnName = "FOLDER_ID" )
@ManyToOne(cascade=CascadeType.MERGE, fetch= FetchType.LAZY )
private FolderTbl parent;

In my unit test, Assertnull fails because getParent() is not null

assertNull( folderTbl.getParent() );

What else do I have to do to stop hibernate loading the parent?

Upvotes: 13

Views: 22858

Answers (5)

ams
ams

Reputation: 62732

Hibernate treats the Lazy fetching as a hint. Here is what the JPA 2.0 spec says on page 364 Table 9.

(Optional) Whether the value of the field or property should be lazily loaded or must be eagerly fetched. The EAGER strategy is a requirement on the persistence provider runtime that the value must be eagerly fetched. The LAZY strategy is a hint to the persistence provider runtime.

Upvotes: 2

Thomas
Thomas

Reputation: 88747

Actually, invoking getParent() might return a proxy instance that shows you there is a parent. If you access fields other than the id the parent would be loaded if necessary.

Note that the parent might be loaded already by the transaction and thus reside in the first level cache. If so, Hibernate normally won't do another query to the database.

As said before, if your entity has a non-transient reference to a parent getParent() will always return a non-null value, even if the parent itself is not loaded yet.

Upvotes: 1

Vinod R
Vinod R

Reputation: 1216

For some scenarios you might need not load the lazy collection at all. You can have a method like below to detach the collection from the session.

public class. .... {
.....
  @JoinColumn( name = "FOLDER_PARENT_ID", referencedColumnName = "FOLDER_ID" )
  @ManyToOne(cascade=CascadeType.MERGE, fetch= FetchType.LAZY )
  private FolderTbl parent;
  ...
  public void detachLazyObjects() {
     parent = null;
  }

Then call this method to detach the class from where you need it to be null. Please use this shortcut sparingly, I would suggest you to think about other ways of doing it before resorting to this solution.

Upvotes: 0

Arun P Johny
Arun P Johny

Reputation: 388436

Even if you set the lazy to true, the parent value will not be null. The lazy load uses a proxy object and assign it to the parent property. When we try to use the parent(call getParent()) it will load the actual parent object using the proxy object.

If you do not want to load the object do not configure the JPA properties for the item and set it as transient.

Upvotes: 15

Jigar Joshi
Jigar Joshi

Reputation: 240946

Parent is configured correctly to load lazily , the point is you are testing it wrongly.

Hibernate will load the object when you invoke the method getParent() , when request to actual object comes it will load .

You can check this thing by configuring show_sql to true. it will invoke a query when you invoke getParent()

Upvotes: 10

Related Questions