Hell All, ** Solved as of now Please see Edit 2 and Edit 3 **
I am NHibernate Newbie- a week old but I though working with it will save me time on new project and not otherwise. I have been banging my head trying to get Nhibernate to save Parent - Child Collection to SQL server database.
My Class Map :
public class OrderMap : ClassMap<Order>
{
public OrderMap()
{
Table("orders");
Not.LazyLoad();
Id(x => x.Id,"id");
Map(x => x.Status, "status").CustomType(typeof(OrderStatus)).Not.Nullable();
Map(x => x.PurchaseOrder, "purchaseorder").Not.Nullable();
Map(x => x.SalesOrder, "salesorder").Not.Nullable();
Map(x => x.SupplierLocationId, "shipfrom").Not.Nullable();
Map(x => x.CustomerLocationId, "shipto").Not.Nullable();
Map(x => x.TypeOfShipment, "shipmenttype").CustomType(typeof (ShipmentType)).Not.Nullable();
HasMany(x => x.OrderLineItems).Table("orderitems").KeyColumns.Add("orderid").Cascade.All();
}
}
public class OrderLineMap : ClassMap { public OrderLineMap() { Table("orderitems");
Not.LazyLoad();
Id(x => x.Id,"id");
Map(x => x.Order.Id, "orderid").Not.Insert().Not.Update();
Map(x => x.PartNumber, "partnumber");
Map(x => x.LineNumber, "linenumber");
Map(x => x.ReleaseNumber, "releasenumber");
Map(x => x.Quantity, "quantity");
Map(x => x.AttachedQuantity, "attached");
Map(x => x.ActivatedQuantity, "activated");
Map(x => x.ReshippedQuantity, "reshipped");
Map(x => x.ReturnRequestQuantity, "requestreturn");
Map(x => x.ReturnedToSupplierQuantity, "returnedtosupplier");
Map(x => x.ReturnedFromResellerQuantity, "returnedfromreseller");
Map(x => x.SplitQuantity, "split");
Map(x => x.CombineQuantity, "combine");
Map(x => x.Status, "status").CustomType(typeof(OrderLineStatus));
Map(x => x.ReferenceOrderId, "reforderid");
Map(x => x.ReferenceOrderLineId, "reforderlineid");
References(oi => oi.Order, "id");
}
}
I am trying to do a Has Many operation. Now I was made to believe (from lot of other posts in SO and Blogs) that it is not possible unless I have a Orders class reference in OrderItems
I am doing testing through Nunit and NH Profiler and insert statement for orders is getting profiled...
OrderTesting.CreateNewOrder : FailedNHibernate.StaleStateException : Unexpected row count: 0; expected: 1
at NHibernate.AdoNet.Expectations.BasicExpectation.VerifyOutcomeNonBatched(Int32 rowCount, IDbCommand statement)
at NHibernate.AdoNet.NonBatchingBatcher.AddToBatch(IExpectation expectation)
at NHibernate.Persister.Collection.AbstractCollectionPersister.PerformInsert(Object ownerId, IPersistentCollection collection, IExpectation expectation, Object entry, Int32 index, Boolean useBatch, Boolean callable, ISessionImplementor session)
at NHibernate.Persister.Collection.AbstractCollectionPersister.Recreate(IPersistentCollection collection, Object id, ISessionImplementor session)
at NHibernate.Action.CollectionRecreateAction.Execute()
at NHibernate.Engine.ActionQueue.Execute(IExecutable executable)
at NHibernate.Engine.ActionQueue.ExecuteActions(IList list)
at NHibernate.Engine.ActionQueue.ExecuteActions()
at NHibernate.Event.Default.AbstractFlushingEventListener.PerformExecutions(IEventSource session)
at NHibernate.Event.Default.DefaultFlushEventListener.OnFlush(FlushEvent event)
at NHibernate.Impl.SessionImpl.Flush()
at NHibernate.Transaction.AdoTransaction.Commit()
at Repository.OrderRepository.Save(Order entity) in OrderRepository.cs: line 30
Any help will be appreciated on how to solve it.
Thank you,
Mar
Edit: Update statement now seen in NH profiler after making changes as Joseph asked:
UPDATE orderitems
SET partnumber = 670712 /* @p0 */,
linenumber = 1 /* @p1 */,
releasenumber = 1 /* @p2 */,
quantity = 2 /* @p3 */,
attached = 0 /* @p4 */,
activated = 0 /* @p5 */,
reshipped = 0 /* @p6 */,
requestreturn = 0 /* @p7 */,
returnedtosupplier = 0 /* @p8 */,
returnedfromreseller = 0 /* @p9 */,
split = 0 /* @p10 */,
combine = 0 /* @p11 */,
status = 0 /* @p12 */,
reforderid = '00000000-0000-0000-0000-000000000000' /* @p13 */,
reforderlineid = '00000000-0000-0000-0000-000000000000' /* @p14 */,
orderid = NULL /* @p15 */
WHERE id = '66f8c7c6-ece6-47c6-93f0-b8e1975a96dc' /* @p16 */
Edit 2 Resolution for Update Statements
IN the Child Class Map change Id(x => x.Id, "id").GeneratedBy.Assigned().UnsavedValue(null);
Edit 3 Improve inserts
Based on the above code NH profiler will show that for each object instance being persisted it will first generate a select statement based on which, it will determine if the object instance is new or dirty. To avoid it use Interceptor as
http://www.kkaok.pe.kr/doc/hibernate/reference/html/example-parentchild.html
Navigate to the very bottom of the article where you will find about how to implement Interceptor. Persistent class will be your base class for your Entities that needs to be saved to database. Interceptor will need to be registered firing the session
I have read that Interceptors have been replaced by events. Could not read a lot on it but Interceptor works great for me.