tags:

views:

886

answers:

3

I am using NHibernate to pull some data out of a legacy db, and I have found several cases where there is a foreign key, but the referenced row has been removed.

When I make my NHibernate mapping (using Fluent NHibernate like so:

References(d => d.Group)
    .WithColumns("groupId", "dataset")
    .SetAttribute("lazy", "true");

) I get an unitialized proxy for Group when loading the root object, followed by an ObjectNotFoundException when I attempt to use it.

If I disable lazy loading, I get an ObjectNotFoundException immediately when loading the root.

Therefore: Is there a way to have NHibernate make the Group null when loading the root? Or is it possible to check the unitialzed proxy somehow, to see if it will succeed in loading the row?

+1  A: 

See Configuration.EntityNotFoundDelegate

Mauricio Scheffer
That seems promising - but it seeems I have access to only the name of the missing entity and - very weird - what seems to be a random instance of the missing entity? Do you know how to put this interface to use?
mookid8000
Haven't tried it, but you should get the entity name and id, see http://fisheye3.atlassian.com/browse/nhibernate/trunk/nhibernate/src/NHibernate/Proxy/IEntityNotFoundDelegate.cs?r=3007
Mauricio Scheffer
This is the default implementation, the one that throws ObjectNotFoundException: http://fisheye3.atlassian.com/browse/nhibernate/trunk/nhibernate/src/NHibernate/Impl/SessionFactoryImpl.cs?r=4091#l76
Mauricio Scheffer
But it's weird - the parameter id of type object seems to be an instance of the entity that could not be found... do you know why that is?
mookid8000
Weird... I see in the code that the delegate is being given the id at all times...
Mauricio Scheffer
(http://fisheye3.atlassian.com/browse/nhibernate/trunk/nhibernate/src/NHibernate/Proxy/AbstractLazyInitializer.cs?r=3097#l87 and http://fisheye3.atlassian.com/browse/nhibernate/trunk/nhibernate/src/NHibernate/Event/Default/DefaultLoadEventListener.cs?r=3976#l111)
Mauricio Scheffer
I think I get it now - NHibernate gives me the id in the form of an example object - i.e. an instance with only the fields of my composite id filled out... but I don't think I can use this interface for my particular problem, because NHibernate throws an `UnresolvableObjectException` after the call
mookid8000
+3  A: 

I found the solution here - i needed to add

.SetAttribute("not-found", "ignore");

to the mapping.

mookid8000
+1  A: 

Hi, have you verified that your referenced property is still loading lazily? In order for NHibernate to load references lazily, it needs to be sure that the reference is NOT NULL. When you set not-found="ignore", you are indirectly telling NHibernate that there is a possibility that the reference may not exist, hence preventing the NOT NULL constraint from being valid. In the case you've described above, you will not encounter an error but you may observe an eager call to the database to load your Group.