I modified my NewUserRole table to have an identity PK of NewUserRoleId. The NewUserId and RoleId columns remain as FKs to the NewUser and Role tables respectively.
I also changed the <bag> elements in my Role and NewUser mappings files to the following:
Code:
<idbag name="NewUsers" table="NewUserRole" inverse="true" lazy="true" fetch="join">
<collection-id column="NewUserRoleId" type="System.Int32">
<generator class="identity"/>
</collection-id>
<key column="RoleId"/>
<many-to-many column="NewUserId" class="NewUser" />
</idbag>
Code:
<idbag name="Roles" table="NewUserRole" inverse="false" lazy="true" fetch="join">
<collection-id column="NewUserRoleId" type="System.Int32">
<generator class="identity"/>
</collection-id>
<key column="NewUserId"/>
<many-to-many column="RoleId" class="Role" />
</idbag>
What is happening now when I save the user with the new role in the Roles collection is I get the following exception:
{NHibernate.ADOException: could not insert collection rows: [xxx.Entity.NewUser.Roles#1] ---> System.InvalidCastException: Failed to convert parameter value from a Object to a Int32. ---> System.InvalidCastException: Object must implement IConvertible.
at System.Convert.ChangeType(Object value, Type conversionType, IFormatProvider provider)
at System.Data.SqlClient.SqlParameter.CoerceValue(Object value, MetaType destinationType)
--- End of inner exception stack trace ---
at System.Data.SqlClient.SqlParameter.CoerceValue(Object value, MetaType destinationType)
at System.Data.SqlClient.SqlParameter.GetCoercedValue()
at System.Data.SqlClient.SqlParameter.Validate(Int32 index)
at System.Data.SqlClient.SqlCommand.BuildParamList(TdsParser parser, SqlParameterCollection parameters)
at System.Data.SqlClient.SqlCommand.BuildExecuteSql(CommandBehavior behavior, String commandText, SqlParameterCollection parameters, _SqlRPC& rpc)
at System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, Boolean async)
at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, DbAsyncResult result)
at System.Data.SqlClient.SqlCommand.InternalExecuteNonQuery(DbAsyncResult result, String methodName, Boolean sendToPipe)
at System.Data.SqlClient.SqlCommand.ExecuteNonQuery()
at NHibernate.Impl.BatcherImpl.ExecuteNonQuery(IDbCommand cmd)
at NHibernate.Impl.NonBatchingBatcher.AddToBatch(IExpectation expectation)
at NHibernate.Persister.Collection.AbstractCollectionPersister.InsertRows(IPersistentCollection collection, Object id, ISessionImplementor session)
--- End of inner exception stack trace ---
at NHibernateTest.Program.Main(String[] args) in D:\CHumber\My Documents\Visual Studio 2005\Projects\NHibernateTest\NHibernateTest\Program.cs:line 49
at System.AppDomain.nExecuteAssembly(Assembly assembly, String[] args)
at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.ThreadHelper.ThreadStart()}
[/code]