2

I have a domain model where a Order has many LineItems. When I create a new Order (with new LineItems) and use PersistenceSpecification to test the mapping, NHibernate throws a PropertyValueException:

var order = new Order() { LineItems = new List<LineItem>() };
order.LineItems.Add(new LineItem());
new PersistenceSpecification<Order>(session)
    .CheckList(o => o.LineItems, order.LineItems) // PropertyValueException
    .VerifyTheMappings();

NHibernate.PropertyValueException: not-null property references a null or transient value LineItem._Order.LineItemsBackref

Domain model

public class Order {
    public virtual Guid Id { get; set; }
    public virtual ICollection<LineItem> LineItems { get; set; }
    [...]
}
public class LineItem {
    public virtual Guid Id { get; set; }
    [...]
}

A LineItem on its own is not interesting, and they will never appear without a Order, so the relationship is unidirectional.

Fluent Mappings/Schema

// OrderMap.cs
Id(x => x.Id).GeneratedBy.GuidComb();
HasMany(x => x.LineItems)
  .Not.Inverse()
  .Not.KeyNullable()
  .Not.KeyUpdate()
  .Cascade.AllDeleteOrphan();

// LineItemMap.cs
Id(x => x.Id).GeneratedBy.GuidComb();

// Schema
CREATE TABLE Orders    ( Id uniqueidentifier NOT NULL, /* ... */ )
CREATE TABLE LineItems ( Id uniqueidentifier NOT NULL, 
                         OrderId uniqueidentifier NOT NULL, /* ... */ )

The foreign key column in the LineItems table is not nullable, so based on the information in this question I specified Not.KeyNullable() and Not.Inverse() to prevent NHibernate from attempting to insert a LineItem with a NULL Id.

I'm using NHibernate 3.3.2.400 and FluentNHibernate 1.3.0.733 (the current latest versions from NuGet).

Community
  • 1
  • 1
Brant Bobby
  • 14,956
  • 14
  • 78
  • 115
  • Please can you provide the schema for the DB tables and some code test code that causes the exception? Also the Order and LineItem properties require the Virtual keyword. – mickfold Mar 13 '13 at 21:23
  • Based on the information you have provided I wrote a test case which worked fine, performing the correct inserts for the order and lineitem. You can download the test VS 2012 project at http://goo.gl/RwF08. – mickfold Mar 13 '13 at 22:28
  • @penfold Ugh, how embarassing. I suppose I've stripped down my example too much. Thank you for taking the time to do what I should have done myself. :) – Brant Bobby Mar 13 '13 at 23:11
  • No problem, it took me very little time ;) If you can update the question so the exception is reproducible I'll have another look at it. – mickfold Mar 14 '13 at 08:56

1 Answers1

1

This occurs because the CheckList() method tries to save each item in the list as soon as you call it. At this point, the parent entity hasn't been saved yet -- That doesn't happen until you call VerifyTheMappings().

Since the relationship is unidirectional, a child entity (LineItem) can't be persisted unless it is part of a parent (Order), and the exception is thrown. (GitHub issue)

I don't have a solution for this yet other than "don't bother testing the list mapping".

Brant Bobby
  • 14,956
  • 14
  • 78
  • 115
  • Thanks for posting this and reporting the issue. Before finding it I thought I was being dense... Did you find a solution in the meantime? If not, what do you think of the solution proposed by me in the issue? – Daniel Hilgarth Jun 05 '13 at 07:49