views:

59

answers:

6

Lets say I have two entities: Stable, and Pony.

Stable has an IList<Pony> with a HasMany mapping configured with Cascade.All().

That means that if I do session.Save(myStable), each Pony in the collection will be saved.

However, what happens if I do this?

Pony myLittlePony = new Pony(Color.Brown);
Stable myStable = new Stable(WoodTypes.RichMahogany);
myStable.Ponies.Add(myLittlePony);

session.Save(myStable);
session.Save(myLittlePony);

Will NHibernate try to save myLittlePony twice? or is NHibernate "smart" enough to know that myLittlePony has already been persisted to the DB?

Are there any performance implications from doing something like this?

+1  A: 

NHibernate is pretty smart, and AFAIK, since myLittlePony would still be in the session and have no changes (IsDirty returning false), it won't trigger another flush to the persistence medium.

wtaniguchi
A: 

It should only get saved once.

And actually nothing usually makes it to the database until you commit the transaction or flush the session.

David Hogue
A: 

If there is SQL Server then run SQL Profiler to see what happen but NHibernate shoud persist that object only ones.

dario-g
A: 

.Save() doesn't do anything other than tell the session about your new object*. NH only works out what to do when the session flushes to the database, which is normally when the transaction commits. It will never write the same entity twice.

(* OK, it may go to the database if you're using a bad identity generator)

James L
+2  A: 

It will probably only be saved once* when the transaction is flushed but you need to mark one side of the relationship (typically the collection) as the inverse side to denote the non-owner of the relationship. This will insure that the behavior is consistent. If you don't mark the collection as the inverse side of the relationship NH will do an insert then update the child object with the foreign key from the parent. This will obviously fail if there's a non-nullable FK constraint.

  • My guess is that internally NH will save the object twice but the second save won't generate a database operation because the object will not have pending changes at that point.
Jamie Ide
Aye, stable is marked as the inverse.
snicker
A: 

I believe what you're doing there is actually what you need to do. The only way that would work with an individual session.Save(myStable); you would need to correctly configure the cascade relationship for the stable class.

Chris Marisic
I mentioned that the cascade relationship for Stable was Cascade.All().
snicker
I missed that, I recommend turning that into a code block to make it more noticeable.
Chris Marisic
Done. Hopefully people see it in the future =]
snicker