Reputation: 181
I am trying to save a complex object which has many referenced elements inside and it works perfectly most of the time.
However in some cases we are getting the below exception,
object references an unsaved transient instance - save the transient instance before flushing or set cascade action for the property to something that would make it autosave. Type: Namespace.Core.Client.ClientDetails, Entity: Namespace.Core.Client.ClientDetails
The problem is, there are around 12 ClientDetails elements inside my complex object which we are trying to save.Is there a way to identify which object instance caused this issue? through NHibernate logging or some other way? My code sample used for save as below,
_repository.Save<SuperParent>(obj);
_repository.Flush();
Please note when i set the Nhibernate show_sql to true i am able to see all the queries properly generated, but when the flush is called, the exception is thrown.
Please help to resolve the issue.
Upvotes: 18
Views: 34839
Reputation: 11
This error also happens when you have a complex object that includes children that are reference data (think ClientType class). If the child has a version element in it's mapping file that maps to an int column in your database, the version number for an existing row should never be set to 0. Nhibernate interprets this as an object to be inserted on a cascade update and will fail as it's attempting to insert a row that already exists.
Upvotes: 1
Reputation: 1400
Edit your mapping to cascade all changes.If you have a Client Class that have many ClientDetails , your xml mapping would be like this
In Client.hbm.xml file you should have :
<set name = "ClientDetails" table = "`ClientDetail`" cascade = "all-delete-orphan" inverse="true">
<key column = "ClientId"/>
<one-to-many class = "ClientDetail"/>
</set>
In ClientDetail.hbm.xml file you should have :
<many-to-one name = "Client" class = "Client" column = "ClientId " />
Upvotes: 1
Reputation: 664
If you read carefully:
...he transient instance before flushing or set cascade action for the property to something that would make it autosave
So, maybe you can add Cascade to the Reference, like this:
References(x => x.ClientDetails).Cascade.All().Column("ClientDetailsId")
.Not.Nullable(); //Or nullable, this depends on your schedule
Upvotes: 4
Reputation: 30803
The exception means that there is an unsaved instance of ClientDetails
referenced by this object. You have to either save it manually before saving the parent
session.Save(Parent.SomeDetail);
or set Cascade.SaveOrUpdate
on the reference-mappings in the parent mapping.
Upvotes: 16