0
votes

I have an aggregate root of an Administration. The Administration object has a 1 to many relationship with Forms. Forms has what is CLOSE to being a many to many relationship with Modules, however there is a property on the link, so I've created a mapping object named FormModule which has a property for a Sequence integer.

I've jiggered around with the Cascade & Inverse settings in the configuration, but I can't figure out the right combination that will allow me to save a new Administration object with all of its dependent objects. I'm using a composite key on the FormModule table, but the KeyReference doesn't appear to have any means for me to set it to save the Modules, and I get the error

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: Module

Here's the code for the classes

public class Administration 
{        
    public virtual int AdministrationId { get; protected set; }

    protected IList<Form> _forms = new List<Form>();
    public virtual IList<Form> Forms
    {
        get { return _forms; }
    }                        
}

public class Form 
{
    public virtual int Id { get; set; }
    public virtual Administration AdminKey { get; protected set; }
    protected IList<FormModule> _formModules = new List<FormModule>();
    public virtual IList<FormModule> FormModules
    {
        get { return _formModules; }
    }
}

public class Module 
{
    public virtual int Id { get; protected set; }
    public virtual Administration AdminKey { get; protected set; }
    protected IList<FormModule> _formModules = new List<FormModule>();
    public virtual IList<FormModule> FormModules
    {
        get { return _formModules; }
    }
}

public class FormModule 
{       
    public virtual Form Form { get; protected set; }
    public virtual Module Module { get; protected set; }
    public virtual int Sequence { get; protected set; }        
}

And heres the code for the Fluent NHibernate config

public class AdministrationMap : ClassMap<Administratio>
{
    public AdministrationMap()
    {            
        Id(x => x.Id)
            .Column("AdministrationId")
            .Not.Nullable()
            .GeneratedBy.Identity();

        HasMany(x => x.Forms)
            .KeyColumn("AdministrationId")                
            .Cascade.All();            
    }
}

public class FormMap : ClassMap<Form>
{
    public FormMap()
    {            
        Id(x => x.Id)
            .Column("FormId")
            .Not.Nullable()
            .GeneratedBy.Identity();

        HasMany(x => x.FormModules)
         .Cascade.All()

        References(x => x.Administration).Column("AdministrationId").Not.Nullable();
    }
}

public class ModuleMap : ClassMap<Module>
{
    public ModuleMap()
    {
        Id(x => x.Id)
            .Column("ModuleId")
            .Not.Nullable()
            .GeneratedBy.Identity();

        HasMany(x => x.FormModules)
            .Cascade.All();
            //.Inverse()  //try this;

        References(x => x.Administration).Column("AdministrationId").Not.Nullable();
    }
}

public class FormModuleMap : ClassMap<FormModule>
{
    public FormModuleMap()
    {
        CompositeId()
          .KeyReference(x => x.Form, "FormId")
          .KeyReference(x => x.Module, "ModuleId");

        Map(x => x.Sequence)
            .Column("SequenceNumber");

        //I've tried these
        //References(x => x.Module).Column(FormModuleTable.Column.FormId).Not.Nullable().Cascade.All();
        //References(x => x.Module).Column(FormModuleTable.Column.ModuleId).Not.Nullable();
    }
}

Does anyone see why I'm getting this error?

1

1 Answers

-1
votes

in general this complete code reads strange for me, but nethertheless

public virtual Module Module { get; protected set; }

How do you initiate the FormModule? Plz post some code you do this. Otherwise I'd say, if you do not set anyvalue toModuleofFormmodulethe value is null and so nhibernate tells you that it'snull or transient``

var formModule = new FormModule ();
formModule.Module = new Module(); //// this doesn't work with your code because of your protected setter

Imho your mapping is correct afais (besides that composite keys are never a good idea)

If you make the module having a public setter, it you should not get any errors with my code mentioned above