I've heard several times that several problems arise in hibernate (especially when using lazy loading). Which are the most common and what can be done about them?
Now, Hibernate can use lazy loading, which means it will load only the required classes, not all classes. It prevents a huge load since the entity is loaded only once when necessary. Lazy loading improves performance by avoiding unnecessary computation and reduce memory requirements.
For lazy loading, we use a proxy object and fire a separate SQL query to load the orderDetailSet. The idea of disabling proxies or lazy loading is considered a bad practice in Hibernate. It can result in fetching and storing a lot of data, irrespective of the need for it.
Lazy Loading means that the object won't be loaded to the Session context until it is accessed in code. Hibernate creates a dynamic Proxy Object subclass that will hit the database only when we first use the object.
1. Working with lazy associations. By default, Hibernate uses lazy select fetching for collections and lazy proxy fetching for single-valued associations. These defaults make sense for most associations in the majority of applications.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With