0
votes

I have made a simple example application to test Fluent NHibernate with the automapping feature but I get an exception when I save.

This is how my example looks like:

public class Item  {
    public virtual int Id { get; protected set; }
    public virtual string Name { get; set; }
    public virtual IList<Detail> Details { get; set; }
    public Item() {
        Details = new List<Detail>();
    }
}
public class Detail {
    public virtual int Id { get; protected set; }
    public virtual int ItemId { get; set; }
    public virtual string Name { get; set; }
}
class Program {
    static void Main(string[] args) {
        var sessionFactory = CreateSessionFactory();
        using (var session = sessionFactory.OpenSession()) {
            using (var transaction = session.BeginTransaction()) {

                Console.WriteLine("Enter name for new item: ");
                var itemName = Console.ReadLine();
                var page = new Item { Name = itemName };
                Console.WriteLine("Enter name of new detail");
                var detailName = Console.ReadLine();
                var detail = new Detail {Name = detailName };
                page.Details.Add(detail);
                session.SaveOrUpdate(page);
                transaction.Commit();
            }
            using (session.BeginTransaction()) {
            }
            Console.ReadKey();
        }

    }
    private static ISessionFactory CreateSessionFactory() {

        var model = AutoMap.AssemblyOf<Program>();

        var sessionFactory = Fluently.Configure()
          .Database(MsSqlConfiguration.MsSql2008.ConnectionString(connection)
          .Cache(c => c.UseQueryCache()
            .ProviderClass<HashtableCacheProvider>())
            .ShowSql())
          .Mappings(m => m.AutoMappings.Add(model))
          .BuildSessionFactory();

        return sessionFactory;
    }
}

This code throws an exception when transaction.Commit() is running and the exception is object references an unsaved transient instance - save the transient instance before flushing.

So can anybody help me figure out what's wrong?

1

1 Answers

2
votes

Your detail instance is "transient", which means that is has not been added to your NHibernate session.

You have two option, where #2 is probably preferred in your case:

1) session.Save(detail) before you flush the session

2) Configure your Details collection to cascade

There are many ways to configure cascading when you are using the automapping feature - I usually prefer to "pollute" my domain model with [Cascade] attributes, and then create a simple implementation of IHasManyConvention and IReferenceConvention that checks for the presence of the attribute and sets the cascading option accordingly.