I have a one-to-many relationship and cannot get cascade to work, once I set cascade I just get “object references an unsaved transient instance …”.
My mapping looks like this
public class SharedDetailsMapping : ClassMap<SharedDetails>
{
public SharedDetailsMapping()
{
Id(x => x.Id).GeneratedBy.Identity();
HasMany(x => x.Foos);
}
}
public class FooMapping : ClassMap<Foo>
{
public FooMapping()
{
Id(x => x.Id).GeneratedBy.Identity();
References(x => x.SharedDetails).Cascade.SaveUpdate();
}
}
The classes like this
public class Foo
{
public Foo()
{
SharedDetails = new SharedDetails();
SharedDetails.Foos.Add(this);
}
public Foo(SharedDetails sharedDetails)
{
SharedDetails = sharedDetails;
SharedDetails.Foos.Add(this);
}
public virtual Guid Id { get; set; }
public virtual SharedDetails SharedDetails { get; set; }
}
public class SharedDetails
{
public SharedDetails()
{
Foos = new List<Foo>();
}
public virtual Guid Id { get; set; }
public virtual IList<Foo> Foos { get; set; }
}
I then want to create Foos without having to save the SharedDetails first if its a new Foo, like so:
using (var transaction = _session.BeginTransaction())
{
var shared = new SharedDetails();
var fooOne = new Foo(shared);
_session.SaveOrUpdate(fooOne);
var fooTwo = new Foo(shared);
_session.SaveOrUpdate(fooTwo);
transaction.Commit();
}
Cannot figure out what I have done wrong, it works ofcurse if I save the SharedDetails first but that is why I have Cascade setup.
In your
SharedDetailsMapping, modify yourHasManyto add.Inverse():This instructs NHibernate that
Fooowns the relationship, which will help it save objects in the relationship in the right order (in this case, theSharedDetailshas to get saved first so we have its ID whenFoois saved).Further info on the purpose/when to use Inverse: NHibernate’s inverse – what does it really mean?
The TL;DNR version:
If you have a bidirectional relationship in your classes (HasMany on one side, References on the other), the HasMany should have
.Inverse().