4

I have two NHibernate entities with a one-to-one relationship. Let's call them Dog and Owner.

public class Dog { public virtual int Id { get;set; } public virtual Owner Owner { get; set; } } public class Owner { public virtual int Id { get; set; } public virtual Dog Dog { get; set; } } 

And Dog may have one or zero owners. The Fluent/NHibernate mappings are as so:

public class DogMap : ClassMap<Dog> { public DogMap() { Table("Dogs"); Id(x => x.Id); HasOne( x=> x.Owner) .Fetch.Join() .Not.LazyLoad(); } } public class OwnerMap : ClassMap<Owner> { public OwnerMap() { Table("Owners"); // Owners share the same primary-key as dogs Id(x => x.Id).GeneratedBy.Foreign("Dog"); References( x => x.Dog) .Unique() .Not.LazyLoad(); } } 

Now I simply wish to select Dogs which don't have an Owner.

I assumed the query would be:

Owner owner = null; var ownerlessDogs = session .QueryOver<Dog>() .Left.JoinAlias(x => x.Owner, () => owner) // Restrict on alias .WhereRestrictionOn(() => owner).IsNull .List(); 

But as you may have guessed, this does not work. It throws 'Object reference not set to ...'.

If I try,

var ownerlessDogs = session .QueryOver<Dog>() .Left.JoinAlias(x => x.Owner, () => owner) // Restrict on property of root object .WhereRestrictionOn(x => x.Owner).IsNull .List(); 

It generates basically generates

SELECT {{relevant columns}} FROM Dogs dogs LEFT OUTER JOIN OWNERS owners WHERE dogs.Id IS NULL 

Almost right, but it is filtering on the primary-key of dogs, rather than the dogs foreign-key on owners.

1 Answer 1

4

With some help from an old post in the Hibernate forum I found a solution:

public class DogMap : ClassMap<Dog> { public DogMap() { Table("Dogs"); Id(x => x.Id); HasOne( x=> x.Owner) .Fetch.Join(); } } public class OwnerMap : ClassMap<Owner> { public OwnerMap() { Table("Owners"); //owners share the same primary-key as dogs Id(x => x.Id).GeneratedBy.Foreign("Dog"); //both sides should be mapped as HasOne HasOne( x => x.Dog) .Constrained() .Fetch.Join(); } } 

And the working query is

var ownerlessDogs = session .QueryOver<Dog>() .Left.JoinAlias(x => x.Owner, () => owner) //this is the trick, restrict on Id .WhereRestrictionOn( x => x.Owner.Id ).IsNull .List(); 
Sign up to request clarification or add additional context in comments.

1 Comment

Apparently not until two days have passed.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.