Will NHibernate attempt to save the same object twice in this scenario?
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?
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.
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.
It should only get saved once.
And actually nothing usually makes it to the database until you commit the transaction or flush the session.
If there is SQL Server then run SQL Profiler to see what happen but NHibernate shoud persist that object only ones.
.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)
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.
精彩评论