When NHibernate cannot find an Entity, is there a way to trace what is trying to load it?
I have a thick client application with a lot of fairly complicated object interrelationships. Occassionally I have an instance where A references an entity X, which gets deleted. The database saves fine but upon reload I get the dreaded NHibernate.UnresolvableObjectException : No row with the given identifier exists[X#1]
.
I accept this is a bug in my software and one what I have to fix. Meanwhile, reality sets in and I need to fix the database - however how I fix it really depends what is referencing it. And I can't find any easy way to tell.
It could be entity A, or it could be entities B-Z. I also don't know what properties on the referencing entity could be loading it, or if it is part of a collection or what.
I'm aware you can set a Configuration.EntityNotFoundDelegate and also specify References(x => x.B).NotFound.Ignore()
(or the equivalent in NHibernate). But this does not get me much closer to finding out what is referencing it. I'm normally reduced to a sometimes painstaking and exhaustive search through my database.
Perhaps with other schemas it would be easier because you c开发者_开发问答ould look at the foreign key constraints and reduce your search space a little. However I am using SQLite and NHibernate does not create foreign key constraints in the SQLite schema.
Ideally I am looking at logging such information. However even if I run it through the debugger very little information is obtained, as the exception is thrown deep in NHibernate code. However even when running attempting to run it through the debugger
Try using the built in SQL logging/debug logging. It should show you everything NHibernate is trying to do.
For anyone that doesn't know how to do this, you need to define the log4net config section in your .config file
<configSections>
<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler,log4net" />
</configSections>
Then, add the actual log4net config section. Set up an appender and a logger. In this example, NHibernate's SQL will be appended to C:\projects\logs\NHibernate.log. In my case, this is a windows service and it has access to that directory. You will want to ensure that the path you set is accessible by your application. You also need to set "ShowSQL" to true when you configure your session factory.
Log4Net Config Section:
<log4net>
<appender name="NHibernateAppender" type="log4net.Appender.RollingFileAppender">
<file value="C:\Projects\logs\NHibernate.log" />
<appendToFile value="true" />
<maximumFileSize value="1000KB" />
<maxSizeRollBackups value="2" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date %level %thread %logger - %message%newline" />
</layout>
</appender>
<logger name="NHibernate.SQL" additivity="true">
<level value="ERROR" />
<appender-ref ref="NHibernateAppender" />
</logger>
</log4net>
精彩评论