NHibernate loop select - fluent-nhibernate

I'm attempting to get data using NHibernate and database return the strange result.
Objects from standart examples: Product and Category.
When im trying to load object with Get<Product>(id), Nhibernate loads infinite cascading loop of referenced entities. I need just single Product and referenced Category.
Its normal NH behavior or im doing something wrong?

Can you provide us with your model and map.
I think it's because both the reference and hasmany are not Lazyload

Related

Few questions related to Atlas HiveMetastoreBridge code

I was going through HiveMetastoreBridge code in Apache Atlas and encountered few doubts.Pardon me if these questions are very naive.
HiveMetastoreBridge code
Why are we clearing relationships in findEntity method?
What does add referred entity does exactly in the background ? To be clear in toTableEntity method we are adding ObjectId of related entites as attributes as well calling addReferredEntity method of AtlasEntity.
In registerInstance method why are we creating references from first entity to other referred entities in else if statement. When will multiple entities be created and why will the first have reference to others?
In importTable method why after creating AtlasEntity processInst we are again creating AtlasEntitiesWithExtInfo createTableProcess and adding process entity and path entity to it? Why not Table entity too?

NHibernate - How to eager load entire object graph and then cache it along with all children and grandchildren

I am not understanding the following scenario. I have a situation where I need to load children and grandchildren along with an entity. I have specified that collections are lazyloaded, but eagerly fetch all rows using detached criteria and setfetchmode to eager. I have the following problem:
NHibernate is taking very long to hydrate the objects - the actual queries run quickly though.
I place the list of results into .net MemoryCacheManager object and seems that after a while the grandchildren seem to drop out the object and I get a lazyload exception.
How to I ensure that the entire graph returned by the results remains in tact in the MemoryCacheManager object? Does session.Evict help me?
Ended up using QueryOver future queries and flattened the results into a DTO and ended up caching the DTO.

Enable lazy loading in a query

I have set NHibernate to not lazy load for my entities. But sometimes when I do queries I don't want all the children of the children to be loaded. The mapping is set up by Fluent NHibernate.
Is there any way when writing the sql for the query to specify which columns to lazy load?
I believe, you're using the wrong approach. Set all mappings to lazy load, and then in the queries eager load only what you really need. This way you won't kill the app.
You can override all the mappings defined in Fluent Mappings in conventions either in class mappings.
There also are different scenarios where NHibernate does the trick (for instance if you load / get one instance all the properties will be fetched as defined in mapping. If you get a list of items it will not happen unless you use Fetch method explicitly).
So could you provide some more details on your question to give an answer that is more precise?

Difference between lazy loading in NHibernate and Entity Framework

While playing around with the Entity Framework and NHibernate using POCO entities, I made the following observation which I find a bit unusual:
I have two POCO entities, an 'Order' and a 'Product'. There is a many-to-many relationship between the two. When I add a product to an Order, I use a 'FixUp' method to ensure that the opposing side of the relationship is also updated i.e. - that the products collection of 'Orders' is also updated.
My Order POCO entity has the following method to do the 'FixUp':
private void FixupProducts(object sender, NotifyCollectionChangedEventArgs e)
{
if(e.NewItems != null)
{
foreach(Product p in e.NewItems)
{
p.Order.Add(this);
}
}
}
While profiling this scenario with EFProf and NHProf, I observed that the Entity Framework generates one more SQL statement than NHibernate, the cause of which seems to be this line:
p.Order.Add(this);
With Entity Framework, the above line causes a select to be executed on the database to return all the orders for the product 'p'. I don't expect this to happen, since I'm using lazy loading and don't actually want to access the products 'Order' collection. I just want to add an order to it.
With NHibernate no attempt is made to load the products collection of orders unless I explicitly try to access it. For example, if I say:
foreach(Order o in product.Orders)
{
Console.WriteLine(o.Id);
}
So ultimately my question is, why does Entity Framework generate the extra SQL statement? Is there a difference in the implementation of lazy loading for the two frameworks that I'm not aware of?
***EDIT TO ORIGINAL
It seems that Entity Framework doesn't behave in a lazy fashion once a method of any kind is called on the collection. Any attempt to add or count (or presumably any other operation on the collection) results in that collection being loaded into memory.
What's interesting is my NHibernate mapping (which is a bag of 'Products - shown below), appears to behave in an 'extra-lazy' fashion, even though my mapping is configured as just being lazy:
<bag name="Products" cascade ="all" table="OrderProduct" mutable="true" lazy="true">
I can 'Add' to the collection without it being loaded into memory. I think that calling 'Count' will result in the orders being loaded unless I configure it as being 'extra-lazy'.
Can anyone comment on whether this is correct?
That is how EF POCO template and its FixUp methods behave. The only ways to avoid this are:
Removing FixUp methods from POCO template
Turn off lazy loading temporarily when assigning Product to Order
It is based on the way how lazy loading is implemented. Every access to property / collection itself triggers lazy loading despite of the operation you want to use on the collection. You will have to avoid build in lazy loading completely to fully avoid it. Here is example how to achieve it for Count method - you can think about similar approach for other methods.
I think that calling 'Count' will result in the orders being loaded
unless I configure it as being 'extra-lazy'.
This is correct, calling Count as well as Contains will be optimized and will not load the whole collection in NHibernate. You may also find this EF vs NHibernate comparison interesting:
Collection with lazy=”extra” – Lazy extra means that NHibernate adapts
to the operations that you might run on top of your collections. That
means that blog.Posts.Count will not force a load of the entire
collection, but rather would create a “select count(*) from Posts
where BlogId = 1” statement, and that blog.Posts.Contains() will
likewise result in a single query rather than paying the price of
loading the entire collection to memory.
Adding a new item to an uninitialized lazy collection will not load the collection. It does not have to be mapped as extra lazy for this. Take a look at this article:
Now, on collections mapped as lazy-loading, Add() operations are
allowed even if the collection is not initialized (i.e. the collection
just acts as a proxy). When adding an object to a collection in this
state, a QueueAdd() method is called that stores the added object in a
secondary collection. Once a lazy initialization is performed, this
secondary collection is merged into the main one (I believe it’s the
DelayedAddAll() method that does this). This can be hard to debug
because lazy load is transparently triggered if you just touch the
collection with the debugger (providing the session is connected at
that moment), and everything gets initialized properly.

eagerly load an entity object graph in nhibernate

I am looking for a way to get the entire object graph back from one of my nhibernate persisted entities. Is there a way to turn off lazy loading in a sessionfactory,session or query?
I have tried setting the FetchMode but it does not eagerly load the entity and child collections.
I just need this for one object to export it out of the database.
You can use CreateMultiQuery or CreateMultiCriteria and keep the default behavior to lazy loading in your mapping.
Take a look at this article for details.