NHibernate: why do non-persistent properties have to be marked as virtual for lazy loading - nhibernate

I kind of get that in order to allow lazy loading, NHibernate needs to generate a proxy class which extends the POCO class. And so I guess NHibernate needs to override the implementation of the persisted properties, and you have to mark them as virtual.
What I don't get is why I have to go round marking almost everything else as virtual as well. For example, I had to mark an IsValid property, which refers to the other properties but obviously isn't itself persistent, and bizarrely I had to mark all the events the class can emit as virtual too.
Anyone know why this is? I'm just curious.
Thanks
David

Related

Background for read-only entity in NHibernate

I read the chapter 10 "read-only entities" in NHibernate Reference Documentation as the following:
http://nhibernate.info/doc/nh/en/index.html#readonly
But unfortunately I DO NOT know why use read-only entities. I think I need some background to understand it, for example:
1. immutable classes means "static" class in C# code? let's use code to display it
public class entity
{
public virtual int Id {get; }
public virtual DateTime CreatedTime
{
get;
//how about I add this becasue it should be set before session.Save()
private set;
}
}
use the read-only entities for performance reason?(no dirty-check and save memoroy)
read-only entities will not be persisted forever
......
Any explanation is helpful, thanks very much in advance.
Lets have some clarification to your questions:
1) immutable classes means "static" class in C# code?
No, immutable means, that the object cannot be modified after creation. Meaning all property values cannot be changed. Usually you have to take care about that yourself in your code if and how to make an object immutable. A normal entity with properties having getters and setters are mutable, because you can call the setter... One way would be to have a readonly backing field and all properties of the object are not exposing a setter...
In case of nhibernate, you can map your entity with immutable flag. If you then try to update a property of a loaded instance, nh might throw an exception.
2) use the read-only entities for performance reason?(no dirty-check and save memory)
Yes that's one very good reason.
For example, if you want to display a list of entities somewhere in your application and you know that within the session you load those entities from the database, you will not modify and save them, you can load them as read-only which will let nh optimize it.
3) read-only entities will not be persisted forever ......
Don't know what you mean with this one?!
Read-only entities simply mean a read-only representation of what you have in your database. Nh expects the instance to be 100% in sync with the database representation. Any changes/updates to that entity would make it not read-only.
So in general it simply depends on what you need. If you just need read only access to entities within one session, you can use this feature to improve performance. Otherwise, do not use it.
Hope this answers your questions.

NHibernate and making an abstract entity base class

I saw in some NHibernate examples that an abstract base entity class is used, which has overridden Equals , GetHashCode , to handle transient entities , proxy object (in lazy loading scenario .. I guess) .
Is it really necessary to implement such an abstract base entity class to derive all my entities ?
Not necessary at all. It just makes things easier because you can put things like the Id on it. As well common functionality like you previously mentioned like Equals/GetHashCode.
Yeah, the base class itself is not required,but overriding Equals and GetHashcode is something you'll want to do on all your entities, so the base class makes thAt a lot less repetetive
In my experience, having a base class that exposes an Id property is really useful to be able to create generic repository methods that take advantage of that, or for automatic mapping conventions.
Overriding Equals, however, is another story.
Doing so forces loading of uninitialized proxies when you compare them (for example, by calling Distinct on a sequence). For that reason, it's better done only for class hierarchies of seldom-changing entities that are likely to be cached.
Overridding Equals is definetely required if you want to do lazy loading.
This is because NHibernate relies on the Equals method to determine equality. The default is reference equality.
When NHibernate implements lazy loading, it uses proxy objects, which are subclasses of the real entity class, with every member overridden to enable lazy loading.
Hence for your application to recognise that a proxy object is the same as the object it is meant to be the real instance - it shouldn't be aware of the proxy object at all.
So you must override the Equals operator to intelligently recognise equality (after checking reference equality ... etc) that objects are equal if their IDs are equal.

Association in Nhibernate with Lazy true

I am working in a project that's work with N Hibernate. Due to performance issues and increasing in complexity of the project we need to do association manually in our code.As we all know for that we have to set lazy property true. What i want know that, is their any way to do association with set lazy property true.We have already created our own methods for filling Association.But still for that also we need to write many queries and code which is not satisfactory.
Please let me know some way for this.
Thanks.
Lazy loading is turned on by default. There is basically two ways how lazy loading is implemented by NHibernate.
Lazy loading of collections
Lazy loading of "single ended" references (many-to-one)
Collections are easy and straight forward. NHibernate uses its own implementation if the collection classes anyway, lazy loading is implemented there.
Single ended references ("normal" associations) are not that easy. Lazy loading is implemented in a proxy. The proxy is a class created at runtime which inherits from the referenced class. That's why everything in the referenced class needs to be virtual. The proxy overrides every member and makes sure that the data is loaded when a member is accessed from outside. The problem with the proxy is, if you reference a base class, you get a proxy from the base class and you can't downcast it to the real class. So be careful when using lazy loading with inherited classes.
Lazy is turned on by default, you need to explicitly turn it off. So you don't need to do anything special to get lazy loading.
When you are optimizing performance, also consider to use batch-fetching.
for single ended associations:
<class name="xx" batch-size="10">
and on collections:
<bag name="xx" .... batch-size="10">
it reduces the N+1 problem a lot (by factor of 10 in this example.).

NHibernate requires events to be virtual?

I'm attempting to map an entity hierarchy using NHibernate almost all of which have events. When attempting to build a session factory however, I get error messages similar to the following:
Core.Domain.Entities.Delivery: method
remove_Scheduled should be virtual
Delivery is an entity in my domain model with an event called Scheduled. Since events cannot be declared virtual I'm at a loss as to how to proceed here. Why would NHibernate need events to be virtual?
Public members must be declared virtual if you use lazy loading because NHibernate will create proxy objects for your entities at runtime. So do not use lazy loading or just declare the event as virtual - that is not so common, but it is possible.
NHibernate creates proxy classes for all lazy loaded entities and uses them where an entity is referenced but not yet loaded. Accessing this proxy triggers loading the real entity from the database. This approach requires to inherit from your entity class at runtime and override the public members hence this members to be virtual.
And there is another solution. You can add proxy="ISomeInterface" to the class declaration. Then you do not need virtual members while proxys just implement the given interface.
I have experienced the same problem with implementing INotifyPropertyChanged on my lazy loaded objects. The problem is that you actually deal with two different .NET instances so that when you fire the NPC event in your real instance you will not receive it from any reference to the proxy. Making it virtual allows the proxy to 'forward' this event. Unfortunately defining events as virtual/overridable is not possible in VB.NET (2005) and hence we had to introduce a C# project with a base class implementing only these virtual events just to get around the VB issue. see also https://forum.hibernate.org/viewtopic.php?f=25&t=990162&start=0
If there are other ways I would be keen to know myself since our method makes proxies a bit less transparant than they should be. Also in the area of auto reconnecting the session when lazy loaded objects need to be initialized seem a bit of a pain.
Regards,
Theo
how does your mapping look like ?
Did you map an event ?
I haven't encountered this issue before, but, then again, I always specify the 'lazy=false' attribute on my class mapping, so that my properties don't have to be declared as virtual. (Since i do not like to declare properties as virtual, if my business model doesnt requires this)
<class name="MyClass" table="MyTable" lazy="false">
</class>

Dependency injection with NHibernate objects

I am wondering how to tell NHibernate to resolve dependencies on my POCO domain objects.
I figured out that methods like CalculateOrderTax should be in the Domain object because they encode domain specific business rules. But once I have two of those I am violating SRP.
It would be no problem to extract those methods to Strategy classes, but I wonder how to make NHibernate load those.
It doesn't seem like a good solution to loop through a list of objects in the repository to do get/set based Dependecy injection before handing the object off to the higher layers.
I am also using Castle Windsor for my Depency injection right now.
I've been using interceptors for similar tasks:
An interceptor that modifies loaded entities:
public class MyInterceptor : EmptyInterceptor
{
public override bool OnLoad(object entity, object id, object[] state, string[] propertyNames, IType[] types)
{
return InjectDependencies(entity as MyEntity);
}
}
Associate it with a session:
nhSessionFactory.OpenSession(myInterceptor);
I've also read somewhere that there would be better support for custom constructor injection in the upcoming 2.1 release but I can't seem to find the reference right now.
As no-one seems to be able to answer your question at the moment I thought I'd suggest restructuring your code to remove the need for the Order to calculate it's own tax.
You could delegate it to a OrderTaxService which takes an Order object and returns an OrderValue object or something along those lines.
This will keep the logic in your domain but remove the need to attach it to your Order objects.
I agree with Garry that you should remove service dependencies from your domain objects as much as possible. Sometimes it makes sense, such as encryption/decryption. In that case you can hide it in the infrastructure using interception or IUserType. I think the latter is favorable when you can use it. This article shows in detail how to do it. I am doing this and it works quite fine.