2
votes

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).

1
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
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 goo.gl/RwF08.mickfold
@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
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

1 Answers

1
votes

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".