NHibernate requires events to be virtual? - fluent-nhibernate

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>

Related

Creating POCO classes that are compatible with NHibernate and EF 4.1

I know that all members of a POCO class for NHibernate must be defined as virtual, and in EF (code first), you only need to set the collection / reference objects as virtual for lazy loading.
So if I want to create POCO objects that are compatible with both EF and NH should I just declare every member of my POCO classes as virtual??
The reason for wanting this is that we're currently evaluating both EF and NHibernate ORM's and if we end up changing our plans down the road, we don't want to have to update our POCO's
EF needs virtual navigation properties for lazy loading but it also uses virtual scalar/complex properties for dynamic change tracking so if you mark all properties as virtual it will be correct approach.
Anyway do you evaluation upfront. virtual properties will be minimal issue if you decide to change ORM later - you will find much harder problems.
Actually you're not forced to declare every property as virtual in NH. If you turn-off the lazy load behaviour ('on' by default) you no longer need to declare all those "virtuals", and may specify case-by-case which properties are lazy-loaded.
So, if you want, you may have a POCO with just reference objects as virtual in both NH and EF.
Sidenote: Anyway, and just for the effort of it, I would declare all properties as virtual and be done with it :)
Or alternatively, if you create an interface or abstract base for your POCO's, you can use the <class name="MyPoco" proxy="IMyPoco"/> attribute in NHibernate which also eliminates the need for virtual properties, since NH then defers to creating its subclasses from the proxy rather than from your POCO directly.

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: why do non-persistent properties have to be marked as virtual for lazy loading

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

How do you map an entity -> interface relationship using Fluent NHibernate?

given the following class definition:
public class Order {
public IProduct Product {get;set;}
}
I have this (fluent) mapping
References(x=>x.Product, "ProductId");
And get this exception: An association from the table Orders refers to an unmapped class, which makes sense because it doesn't know what implementation I will pass to it.
I understand why I have to define the type in the mapping (IProduct could be anything) but I'm not sure how to do it.
Thanks,
Kyle
I think what you're looking for is .References<Product>(x=>x.Product, "ProductId");
Incidentally the same is true for .HasMany<>
This seems to do the same as <... class="Product" /> in xml
I wouldn't recommend mapping to the interface as it breaks the whole point of using one - you run into problems as soon as it starts implementing IStorable and NH can't cope with the multiple inheritance.
Try mapping the interface IProduct instead of the concrete class Product. (Note, I'm not talking about mapping the Product field of class Order.)
You could map the interface->implementation relationship as an inheritance relationship, using an appropriate inheritance model.
That would mean mapping IProduct and then creating a subclass map of Product in the IProduct mapping, for example using table-per-hierarchy.
That would also let you map additional data in the product class that is not part of the IProduct interface, and also let you map additional IProduct implementations in the same way if you wish to.
I've been working on improving the support for proxy interfaces in Fluent. There were a couple of useful patches attached to issues 256 and 257, but they really needed everything specified manually. I've taken these a step further and added support for setting proxies and changing the types of references from the inferred (which would be the proxy) to the underlying mapped class, and added a new convention (ProxyConvention) to set it all up automatically - just instantiate it with a function to derive the proxy interface from a mapped class, and it should take care of the rest.
The one loophole at the moment is that it can't pick up any definitions specified explicitly in .hbm.xml files.
The patch is attached to issue 256