简体   繁体   中英

What does it mean to fetch eagerly in Hibernate

I was reading the ProSpring 3 book which outlines how to use Spring and Hibernate together. But, I came across the statement that 'you can fetch the association eagerly'. My question is:

What does fetching an association eagerly in Hibernate really mean and how does that affect, or even if it affects, the performance of the query in Hibernate?

Eager fetching means that when the parent entity is looked up from the database, all of the associated entities are looked up at the same time.

Lazy fetching (the opposite) means that only the parent entity's own fields are looked up. The associated entities are populated with proxies that will look them up from the database if/when they are referenced.

So the primary difference in query performance is in terms of when the lookup for the associated entities happens. With eager fetching this will always happen at the same time that the parent is loaded, while with lazy fetching this will be later (and possibly never).


Lazy loading sounds like the clear winner due to the on-demand behaviour, but there are a few caveats to bear in mind. Firstly, the scoping of your connections can be very difficult to ascertain. What looks like a normal entity object actually has an embedded database connection in it that can be invoked at any point by "normal" getter methods (or worse by the clients of these methods). Knowing when you can close the connection or return it to a pool is almost impossible. Similarly, this behaviour can cause confusion when a "simple" object doesn't have its fields set during debugging, or throws SQL exceptions when you're just iterating over a collection that was returned from a getter method on said "simple" object.

Additionally, aggregate performance is likely to be worse if the associated entities are loaded separately from the parent entity. There's the extra overhead of another SQL round-trip, but more importantly the database can't reuse existing lookups in joins, etc. In situations where the associated entities are always used, eager fetching is likely to be faster and easier to support.

IMHO (and speaking from experience), lazy loading should be a carefully considered optimisation, in those cases where there's a good chance that relationships will not be used.

Let me illustrate this with a simple example: Suppose that you are trying to write a query to get for example a User object with all his/her Post s (one to many relationship). When you are eagerly fetching it means that the Post records will be loaded into the persistence context with your User object.

In the case that you are loading lazily it means that Hibernate won't load any data apart from your User object. In both cases Hibernate will use Proxy objects and if you try to access your User 's Post s when you are lazy you may get the dreaded LazyInitializationException .

My suggestion is that in most cases you should set everything to be loaded lazily and you can use the JOIN FETCH syntax in your JPQL queries. This works with the Criteria API in a similar way as well.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM