Skip to main content

NHibernate–Lazy loading without a proxy

Yes, it is 2023 and yes I'm still using NHibernate at some of my projects(sorry old habits die hard).

One of the things that is really handy but can bite you in the foot as easily, is lazy loading.

What is lazy loading?

Lazy loading is used to delay the retrieval of related data from a database until it is actually accessed or requested by the application. ORM frameworks, like NHibernate or Entity Framework, map database tables to objects in your programming language, making it easier to work with relational data in an object-oriented manner.

When an ORM employs lazy loading for related data, it means that the ORM does not fetch all the associated data immediately when you query for the main entity. Instead, it loads the related data from the database only when you explicitly access or request that data. This approach helps improve performance by reducing the initial amount of data fetched from the database and minimizing the number of database queries.

Here's an example to illustrate how lazy loading works in the context of ORM:

Let's say you have two entities, Author and Book, with a one-to-many relationship (an author can have multiple books). With lazy loading enabled, if you retrieve an Author object from the database, the ORM might only fetch the author's information and not load the associated books immediately. Only when you access the books property of the Author object will the ORM issue an additional query to fetch the books associated with that author.

Benefits of lazy loading in ORM:

  1. Reduced Data Transfer: Lazy loading minimizes the amount of data transferred from the database to the application initially, which can lead to faster query execution and lower network traffic.

  2. Efficient Resource Usage: Since related data is loaded only when needed, resources like memory and network connections are used more efficiently.

  3. Improved Performance: Loading related data on-demand can lead to faster initial query execution times, which is especially beneficial in scenarios where not all related data is required for every operation.

However, lazy loading can also introduce some challenges:

  1. N+1 Query Problem: If lazy loading is used excessively and not managed properly, it can lead to the "N+1 query problem," where fetching a collection of entities results in N additional queries to load their related data. This can cause performance issues.

  2. Unintentional Overhead: Developers need to be mindful of when and how they access related data to avoid triggering unnecessary database queries and performance bottlenecks.

  3. Complexity: Managing lazy loading and ensuring that related data is loaded appropriately can add complexity to the application code.

To address these challenges, many ORM frameworks provide options for customizing lazy loading behavior, like specifying eager loading (loading related data along with the main entity) or utilizing batch loading techniques to minimize the number of queries. Developers should carefully consider the trade-offs between eager and lazy loading based on their specific application's requirements and performance considerations.

How lazy loading works in NHibernate

In NHibernate lazy loading is enabled by default. To make this work NHibernate uses out-of-the-box a proxy object. This proxy objects sits in between your object and an associated relation(for example between the Author and its Books).

Remark: To make this work NHibernate requires that all properties and methods in your object are declared as virtual if lazy loading is enabled.

Here is an example in NHibernate:

Lazy loading without a proxy

Although the usage of proxies is the default way in NHibernate it is a leaky abstraction and can result to unexpected behavior. For example as explained in this post, the following code will not work as expected:

We are checking the type of what is returned but this is not the object itself but instead a proxy instance.

To avoid this issue, you can change the lazy loading behavior in NHibernate to not using a proxy but fetch the actual object the first time you access the property.

This is how to do it using the conformist mapping:

Or using Fluent NHibernate:

Popular posts from this blog

DevToys–A swiss army knife for developers

As a developer there are a lot of small tasks you need to do as part of your coding, debugging and testing activities.  DevToys is an offline windows app that tries to help you with these tasks. Instead of using different websites you get a fully offline experience offering help for a large list of tasks. Many tools are available. Here is the current list: Converters JSON <> YAML Timestamp Number Base Cron Parser Encoders / Decoders HTML URL Base64 Text & Image GZip JWT Decoder Formatters JSON SQL XML Generators Hash (MD5, SHA1, SHA256, SHA512) UUID 1 and 4 Lorem Ipsum Checksum Text Escape / Unescape Inspector & Case Converter Regex Tester Text Comparer XML Validator Markdown Preview Graphic Color B

Help! I accidently enabled HSTS–on localhost

I ran into an issue after accidently enabling HSTS for a website on localhost. This was not an issue for the original website that was running in IIS and had a certificate configured. But when I tried to run an Angular app a little bit later on http://localhost:4200 the browser redirected me immediately to https://localhost . Whoops! That was not what I wanted in this case. To fix it, you need to go the network settings of your browser, there are available at: chrome://net-internals/#hsts edge://net-internals/#hsts brave://net-internals/#hsts Enter ‘localhost’ in the domain textbox under the Delete domain security policies section and hit Delete . That should do the trick…

Azure DevOps/ GitHub emoji

I’m really bad at remembering emoji’s. So here is cheat sheet with all emoji’s that can be used in tools that support the github emoji markdown markup: All credits go to rcaviers who created this list.