Best way to save a Parent object - nhibernate

Just wondering what's the best-practice for saving a Parent that ordinarily contains a collection of Child objects (many-to-many in my case), but that collection in the Parent is currently set to null because it hasn't been loaded?
In my case, the Parent is passed to my service layer from a Web page. The web page has only populated the Parent's simple attributes from a form.
I know there are several Child objects linked to the Parent in the database, but the 'children' property is currently null.
If I save the Parent, even though my of Children is set to cascade="none", when I save Parent, all the links are deleted (I can even see the delete statements NHibernate issues in the logs).
I can think of several ways to solve this:
1) Load the children seperately and then set the Parent's child collection to them and then save the parent (works but this is an additional trip to the database).
2) Issue an update on ONLY the simple properties using HQL or Native SQL.
Update: I'm not sure my cascade behaviour is working properly actually. From the docs, it suggests that NHibernate won't mess with my collection unless cascade is set to save-update, all-delete-orphan etc. But this is my mapping
(from Order.hbm.xml)
<bag name="OrderItems" table="order_item" cascade="none" lazy="true">
<key column ="order_id" />
<many-to-many class="MenuItem" column="item_id"/>
</bag>
When Order.OrderItems is null, and I save my Order object using SaveOrUpdate(Order), it definately deletes the collection. I want them to be preserved. Is my configuration wrong or something?
Thanks

I wouldn't actually use the real Parent object for passing data from UI to the service layer. You could instead implement a lightweight class (Data transfer object) that would contain just those basic properties and then pass it to the service tier and populate (either manually or using AutoMapper) the parent's properties.

Related

NHibernate Event Upon Insert of Entity into Dictionary- Reference to Parent Object

I have an entity (the "parent") which contains a dictionary with unidirection one-to-many references to instances of a "child" entities. The HBM file for the parent contains the following attributes for the map tag: cascade="all-delete-orphan" inverse="false".
An instance of the parent is persisted to the database, then retrieved and a new child instance added to the parent instance dictionary. When the transaction for this update is committed I've noticed that the OnPreInsert method is fired on a registered instance of IPreInsertEventListener, with the child instance being inside the Entity property of the PreInsertEvent instance passed in.
Is there any way I can find a reference to the parent class in the listener when this dictionary insert is committed? I've tried to register a IPreCollectionUpdateEventListener and this doesn't pick anything up.
As I've said, this is a unidirectionary relationship, and I know that I could achieve what I want by making it bidirectional, but this is something that I'd rather not do.
One option would be to register a IPreUpdateEventListener instance as well.
In this case, you could trap the parent object instead and iterate its children to do your stuff.

Saving objects in EntityFramework over WCF causes related entities to be created

A couple of times on this current project developers have hit the same problem:
An object with related entities, i.e. an Order with a related Customer is sent back via WCF to entitywork to be saved. If the object is new we use AddObject() to put it back in the context and if it has changed, then we use ApplyCurrentValues() to update the object.
The Order object has changed, but the Customer object has not (unless the streaming via WCF affects it in some way). However, when calling SaveChanges() on the context the main object, Order in this example, is saved, but a new copy of Customer is also added to the database.
The workaround that we have found is to set the reference to Customer on Order to null before calling SaveChanges(), however this feels like a bit of a kludge.
What I'm looking for is the "correct" way to solve this problem, something akin to LazySaving = false, i.e. only save the object changed and don't try to create all the related objects.
Thanks in advance for any pointers.
I am not sure about Entity Framework, but I ran into this issue recently with NHibernate. I solved it by implementing save as follows
(1) Retrieve original entity from DB
(2) Update original entity from WCF Data Transfer object using AutoMapper
(3) Save original entity
I am not sure if you are trying to use your entities as DataContracts, in my experience its always better to use Data Transfer Objects rather than entities as you DataContract. If you dont, you continually run into all kinds of trouble, and DTO+AutoMapper gives you the control to solve most issues that you run into
http://automapper.codeplex.com/

update parent cause lazy load on child collection

I have parent+child relationship and child collection is mapped as lazy. I fetch a parent, and of course because of the lazy loading child collection is not loaded. But when I want to update my parent NH first loads child collection. I'm interesting is this by default, or I went wrong somewhere. Collection is lazy, inverse=true and cascade="all-delete-orphan". I assume that because of cascade mapping NH wants to check changes on the child collection and it is accessed for the first time so lazy load did it's job. Please can somebody confirm this.
When updating the parent object NHibernate should not have to load the child collection unless you are modifying the foreign key relationship column.
Inverse="true"
This means that the objects in the child collection are responsible for managing the relationship with the parent.
cascade="all-delete-orphan"
When adding a new child object to the collection it will cascade to the DB without you having to explicitly call Session.Save(childobj) first. It also means if you delete the parent object all of the child collection object will also be deleted from the DB.
I use those exact settings for my child collection relationships and do not see this behaviour.
Could you post your mappings/fluent maps/test code which may give more insight into the issue at hand?

nHibernate Save One-To-Many

I have a parent class that contains a list of children. I have the parent and child mapped bidirectional with a has-many and an inverse on the parent with cascade.all turned on. If I modify an object in the child list, but no property on the parent, nHibernate does not save the child. If I modify a property on the parent everything saves fine. Is this by design or is there a special property I need to set?
This might have something to do with the way you are adding the children to the collection. In a bidirectional, you have to manage both sides of the relationship in the code. Consider the example from the Fluent Nhibernate Getting Started Guide. Check the Store Entity.
A Store has many Employees. The Staff property of Store is collection of Employees. The relationship is setup as bidirectional.
Store has the following method
public virtual void AddEmployee(Employee employee)
{
employee.Store = this;
Staff.Add(employee);
}
As you can see, the childs Parent property needs to be set to the parent object. If this is not done, then Nhibernate will not be able understand who the parent of the child is and cannot automatically save the child if only the child is modified and the SaveOrUpdate(parent) is called.
You need to do both.
I figured it out. I was testing auditing using various listners. When I attached to the IFlushEntityListner it caused saves to stop working. Geez that was frustrating. Thanks everyone!

lazy-loading and Eagerly loading in Nhibernate

I am using Nhibernate but still i am confused about (lazy-loading and Eagerly loading) these two topics due to poor understanding of Nhibernate.
Please define me lazy-loading and Eagerly loading in simple words.
Also why we use castle.Dynamic Proxy ?
Lazy loading and eager loading are concepts that must be present in every ORM.
Let's take a parent-child relation:
class Parent {
String name;
List<Child> childs;
}
class Child {
String name;
}
When you load an element of Parent, the ORM must decide if it loads the childs collection also (through a join for example) or if it delays the query to load the childs until you actually access the collection
parent.childs.get(0)
When you load the childs collection ahead, ie, before accessing the collection, it is eagerly loading because you are expecting to access the childs. This can be done in a single query, with the disadvantage of bringing more data from the DB.
When you delay the load until the actual collection is accessed, it is called lazy loading, because you are only getting the childs when they are strictly required. This has the benefit of getting only the data when its needed, at the cost of extra queries (for mor on this topic you can query google for "N+1 select hibernate" for example).
If you want to trigger the query for retrieving the childs when the collection is being accessed, you need some sort of callback/interception on the childs collection. This is done through a proxy on the collection, so you can intercept every access to the collection to get data from the db. That's why you need a proxy/interception library such as Castle.
Lazy loading = waiting until code explicitly accesses a property/collection before loading it from the database.
Eager loading = proactively loading that data ahead of time, regardless of whether the code ever uses it or not.
Proxies are used to intercept access to said properties/collections in order to instigate the load.