开发者

NHibernate, legacy database, foreign keys that aren't

The project I'm working on has a legacy database with lots of information in it that's used to alter application behavior. Basically I'm stuck with something that I have to be super careful about changing.

Onto my problem. In this database is a table and in this table is a column. This column contains integers and most of the pre-existing data have a value of zero for this column.

The problem is that this column is in fact a foreign key reference to another entity, it was just never defined as such in the database schema.

Now in my new code I defined my Fluent-NHibernate mapping to treat this column as a Reference so that I don't have to deal with entity id's directly in my code. This works fine until I come across an entity that has a value of 0 in this column.

NHibernate thinks that a value of 0 is a valid reference. When my code tries to use that referenced object I get an ObjectNotFoundException as obviously there is no object in my database with an id of 0.

How can I, either through mapping or some kind of 开发者_如何学运维convention (I'm using Fluent-nhibernate), get NHibernate to treat id's that are 0 the same as if it was NULL?


I found the API to tell NHibernate to ignore references that aren't found (NotFound.Ignore()), rather than throw the exception. I was confused by all the mentions of SetAttribute() I found online which is for an older version of fluent-nhibernate than I am using.


I'm in the same situation. The problem with not-found=ignore is that it will requery the relationship everytime you try to access it even though it has already been run in the original query. Basically, hibernate doesn't store the fact that there is no record for the otherside of the relationship. You can see this in action in the debug log. Here's an example from my current project.

loading entity:
attempting to resolve:
object not resolved in any cache:
Fetching entity:
loading entity:
Opened new IDbCommand, open IDbCommands: 1
Building an IDbCommand object for the SqlString: SELECT townshipdo0_.TOWNSHIP_CODE as TOWNSHIP1_203_0_, townshipdo0_.TOWNSHIP_NAME as TOWNSHIP2_203_0_, townshipdo0_.TOWNSHIP_TYPE_CODE as TOWNSHIP3_203_0_, townshipdo0_.TOWN_ACTIVE_FLAG as TOWN4_203_0_, townshipdo0_.VERS as VERS203_0_ FROM VTTOW_TOWN_CODE townshipdo0_ WHERE townshipdo0_.TOWNSHIP_CODE=?
binding ' ' to parameter: 0
SELECT townshipdo0_.TOWNSHIP_CODE as TOWNSHIP1_203_0_, townshipdo0_.TOWNSHIP_NAME as TOWNSHIP2_203_0_, townshipdo0_.TOWNSHIP_TYPE_CODE as TOWNSHIP3_203_0_, townshipdo0_.TOWN_ACTIVE_FLAG as TOWN4_203_0_, townshipdo0_.VERS as VERS203_0_ FROM VTTOW_TOWN_CODE townshipdo0_ WHERE townshipdo0_.TOWNSHIP_CODE=:p0

You can see it trying to bind ' ', the DB for this app uses empty space to represent null (stupid I know). But each time nhibernate encounters this, it will try to look it up from the DB because it can't find the record in the cache and doesn't know that it's actually NULL.

It would be nice if we could specify a default null value to ignore in configuration. Currently the only way to get around this is to use queries to load your relationships rather than relying on nhibernate generated queries.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜