2

I am performing some tests with SpringData and Hibernate and found some interesting behavior on lazy loading and findBy... methods.

I have the following method on a child class.

List findByArtistCredit(Long artistCreditId);

and the following mapping between Recording and ArtistCredit...

@ManyToOne(fetch=FetchType.LAZY)
@JoinColumn(name="artist_credit" , referencedColumnName="artist_credit_id")
private ArtistCredit artistCreditReference; 

on the "One" side...

@OneToMany(fetch=FetchType.LAZY,mappedBy="artistCreditReference")
private Set<Recording> recordings; 

And what happens is that the collection on the "Many side" is being eagerly fetched...

Does anyone know "why is happening?"

Any answer is wellcome.

Regards.

2 Answers 2

5

Normally it shouldn't be eagerly fetched base on what you have done.

The recordings should be a lazy-loading proxy which loading is only triggered when needed.

However it is a common mistake that lazy-loading is accidentally triggered:

  1. You may have accidentally accessed that field in your code, for example, in toString()/hashCode()/equals().
  2. You are inspecting your object state through a debugger, which will in turns trigger toString() or access to the lazy-loading field.

I strongly suggest you turn on SQL loading and inspect when is the lazy loading be triggered. Tools like JdbcDsLog or even simply turn on the SQL logger of Hibernate should help

Sign up to request clarification or add additional context in comments.

Comments

-1

By default, Hibernate will fetch related objects when they are not in a collection. The FetchType is just a hint. The reason is because the normally Hibernate MUST load the object to determine if the field should be NULL or not. If the field were a collection, then the collection can always be non-NULL, so Hibernate can replace the collection with a proxy that will load on-demand. But with a single object, there is no way to put a proxy is that can return NULL to the getter.

3 Comments

That's not true as far as I can tell. You can very well define FetchType.LAZY on a ...ToOne relation, effectifly breaking the join fetch in the query. That makes sense as the foreign key column has a null value in the database.
this answer is obviously wrong (and irrelevant). Logically, for case of a single object (xxxToOne), the ID of that "One" side will be there with in the record of "Many" side. When data is retrieved for the "Many" side, Hibernate already have information on whether that FK is null (hence give a null object ref) or contains value (so it makes a proxy for it)
So, if this is wrong, how can the getter for this single value field return NULL if the value is lazy-loaded. The normal process of implementing the lazy load is to replace the container with a proxy that loads the contents when the container is dereferenced. If the object referenced in the field is replaced by a proxy, then the getter will never return NULL. It will always return the proxy. If the getter does return NULL, then there is no proxy to lazy load the actual object.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.