What are the main problems when using hibernate lazy loading?
I've heard several times that several problems arise in hibernate (especially when using lazy loading). W开发者_Python百科hich are the most common and what can be done about them?
The most common probably is the n+1 select problem, when lazy loading of a collection results in hitting the DB with n+1 separate queries instead of a single join query.
The antidote to such issues is common sense :-) I believe that all relevant sources (first and foremost the Hibernate reference) discuss this (and other related) issues extensively, together with resolutions and workarounds. In brief, you should not copy recipes blindly from the cookbook - measure the performance of your code and tune it accordingly. If you see too many selects issued, you can selectively switch from lazy loading to join or subselect fetching strategy for that specific property/class/query. (Note that both of these have their own potential drawbacks, so again, performance measurement is key.)
A different, albet much rarer, problem arises when the client code depends on the actual type of an entity/property (e.g. by testing it with instanceof
. Such code breaks if it encounters a proxy object, which is not an instance of the concrete class it stands for. However, it is not the best idea to write such code anyway, and it should very rarely be necessary. However, sometimes it is inherited with legacy code, thus causing a conflict which may be difficult to work around.
First of all, EAGER fetching is a much bigger problem. Lazy fetching is the way to go since it allows you to fetch just as much info as you need.
The only problem you can have is LazyInitializationException
if you don't initialize the lazy associations while the Session
is open, and you attempt to navigate an uninitialized Proxy/Collection after the Persistence Context is closed.
The N+1 query problem can arise for both eager (when you execute a JPQL query that doesn't explicitly fetch all the eager associations) and lazy associations, and the solution is the same as with LazyInitializationException
.
However, you can detect all N+1 query issues automatically during testing. Check out this datasource-proxy based utility for more details on this topic.
The fetch strategy of HQL can be used to deliberately specify what needs to be loaded. For example (from Hibernate Reference):
from Cat as cat
inner join fetch cat.mate
left join fetch cat.kittens
Unfortunately, Hibernate does not support all standard select capabilities of SQL as part of HQL, which depending on the project requirements, could be prohibitive. For example, select from select is not possible, but is frequently required for creating reports or performing data analysis.
This can be overcome by Hibernate's capability of executing SQL. However, this approach does not provide object-oriented goodness of HQL (e.g. all joins have to be crafted manually).
精彩评论