NHibernate, how to disable additional selects for orphaned references

572 views Asked by At

I'm using NHibernate for data access and have a situation like this

public class B
{
   public virtual long Id { get; set;}
   // ...
}
public class B
{
   public virtual long Id { get; set;}
   public virtual A AReference { get; set; }
   // ...
}

and mapping

public class BMapping : ClassMapping<B>
{
    // ...
        ManyToOne(x => x.AReference, mapper =>
        {
            mapper.ForeignKey("none");
            mapper.Insert(false);
            mapper.Update(false);
            mapper.Column("a_id");
            mapper.Fetch(FetchKind.Join);
            mapper.NotFound(NotFoundMode.Ignore);
        });
    // ...
}

My problem is that there is no foreign key constraint between tableA and tableB, so there are cases where tableB references nonexistent items. (I know that's bad, but I can't do anything about it.)

Setting

mapper.NotFound(NotFoundMode.Ignore);

allows me to retrieve data without "No row with the given identifier exists" exceptions, but it seems NHibernate is trying to load those orphaned items using separate selects like

SELECT ... FROM tableA WHERE tableA.ID = ?

Can I disable that additional queries and how?

1

There are 1 answers

4
Radim Köhler On BEST ANSWER

As discussed here NHibernate Prevent Lazy Loading of unmatched reference and here Lazy loading for NHibernate with Ignore.NotFound the point is:

When you specify the .NotFound().Ignore() this forces the entity to be eagerly loaded and cannot be overriden with the .LazyLoad(). NHibernate does this because it has to be sure that relationship exists or doesn't exist since you are not relying on the database to enforce this.

Check this for

and mostly the link provided there

How to use 0 instead of null for foreign keys

to get some understanding how to create custom PocoEntityTuplizer to be used that.

.. during the build process of the Person entity will collection object[] values contain also CountryProxy. Let's say that missing in DB is one with Id == 0 (use your own logic there as needed). This proxy will be replaced with null so no SELECT will be executed...