Hello,
I am getting the following error from when I am saving an object. I have cut out my own stack from the error message to..
Quote:
[InvalidCastException: Object must implement IConvertible.]
System.Convert.ChangeType(Object value, Type conversionType, IFormatProvider provider) +2560525
System.Data.SqlClient.SqlParameter.CoerceValue(Object value, MetaType destinationType) +896
[InvalidCastException: Failed to convert parameter value from a Object to a Int32.]
System.Data.SqlClient.SqlParameter.CoerceValue(Object value, MetaType destinationType) +943
System.Data.SqlClient.SqlParameter.GetCoercedValue() +29
System.Data.SqlClient.SqlParameter.Validate(Int32 index, Boolean isCommandProc) +97
System.Data.SqlClient.SqlCommand.BuildParamList(TdsParser parser, SqlParameterCollection parameters) +166
System.Data.SqlClient.SqlCommand.BuildExecuteSql(CommandBehavior behavior, String commandText, SqlParameterCollection parameters, _SqlRPC& rpc) +253
System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, Boolean async) +1005
System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, DbAsyncResult result) +132
System.Data.SqlClient.SqlCommand.InternalExecuteNonQuery(DbAsyncResult result, String methodName, Boolean sendToPipe) +149
System.Data.SqlClient.SqlCommand.ExecuteNonQuery() +135
NHibernate.AdoNet.AbstractBatcher.ExecuteNonQuery(IDbCommand cmd) in D:\NHibernate\src\src\NHibernate\AdoNet\AbstractBatcher.cs:196
NHibernate.AdoNet.NonBatchingBatcher.AddToBatch(IExpectation expectation) in D:\NHibernate\src\src\NHibernate\AdoNet\NonBatchingBatcher.cs:39
NHibernate.Persister.Collection.BasicCollectionPersister.DoUpdateRows(Object id, IPersistentCollection collection, ISessionImplementor session) in D:\NHibernate\src\src\NHibernate\Persister\Collection\BasicCollectionPersister.cs:230
NHibernate.Persister.Collection.AbstractCollectionPersister.UpdateRows(IPersistentCollection collection, Object id, ISessionImplementor session) in D:\NHibernate\src\src\NHibernate\Persister\Collection\AbstractCollectionPersister.cs:1315
NHibernate.Action.CollectionUpdateAction.Execute() in D:\NHibernate\src\src\NHibernate\Action\CollectionUpdateAction.cs:55
NHibernate.Engine.ActionQueue.Execute(IExecutable executable) in D:\NHibernate\src\src\NHibernate\Engine\ActionQueue.cs:130
NHibernate.Engine.ActionQueue.ExecuteActions(IList list) in D:\NHibernate\src\src\NHibernate\Engine\ActionQueue.cs:113
NHibernate.Engine.ActionQueue.ExecuteActions() in D:\NHibernate\src\src\NHibernate\Engine\ActionQueue.cs:149
NHibernate.Event.Default.AbstractFlushingEventListener.PerformExecutions(IEventSource session) in D:\NHibernate\src\src\NHibernate\Event\Default\AbstractFlushingEventListener.cs:240
NHibernate.Event.Default.DefaultFlushEventListener.OnFlush(FlushEvent event) in D:\NHibernate\src\src\NHibernate\Event\Default\DefaultFlushEventListener.cs:19
NHibernate.Impl.SessionImpl.Flush() in D:\NHibernate\src\src\NHibernate\Impl\SessionImpl.cs:1187
When I look through the log files I see the following SQL
Quote:
2008-09-12 14:38:04,995 [4] DEBUG NHibernate.AdoNet.AbstractBatcher - Opened new IDbCommand, open IDbCommands: 1
2008-09-12 14:38:04,995 [4] DEBUG NHibernate.AdoNet.AbstractBatcher - Building an IDbCommand object for the SqlString: UPDATE OrganizationSetting SET SettingValue = ?, SettingId = ? WHERE Id = ?
2008-09-12 14:38:04,995 [4] DEBUG NHibernate.Type.StringType - binding 'Quote' to parameter: 0
2008-09-12 14:38:04,995 [4] DEBUG NHibernate.Type.Int32Type - binding '1' to parameter: 1
2008-09-12 14:38:04,995 [4] DEBUG NHibernate.Type.Int32Type - binding 'System.Object' to parameter: 2
2008-09-12 14:38:04,995 [4] DEBUG NHibernate.SQL - UPDATE OrganizationSetting SET SettingValue = @p0, SettingId = @p1 WHERE Id = @p2; @p0 = 'Quote', @p1 = '1', @p2 = 'System.Object'
2008-09-12 14:38:04,995 [4] DEBUG NHibernate.Connection.DriverConnectionProvider - Obtaining IDbConnection from Driver
The error here is occuring because we are binding the string value of System.Object to an integer field. Interestingly NHibernate sees that this is an integer based on this log statement:
Quote:
NHibernate.Type.Int32Type - binding 'System.Object' to parameter: 2
My mapping file is:
Code:
<class name="Cutter.Domain.Membership.Organization" table="Organization" lazy="true">
<id name="Id" column="OrganizationId">
<generator class="guid" />
</id>
<property name="Name" column="Name" type="String" length="50"/>
<property name="IsInitalized" />
<property name="DateCreated" type="DateTime" update="false"/>
<component name="Phone" class="Cutter.PhoneNumber">
<property name="Number" column="PhoneNumber"></property>
<property name="AreaCode" column="AreaCode"/>
<property name="Extension" column="Extension"/>
<property name="CountryCode" column="CountryCode"/>
</component>
<component class="Cutter.Address" name="Address">
<property name="AddressLine1"></property>
<property name="AddressLine2"></property>
<property name="City"></property>
<property name="State"></property>
<property name="PostalCode"></property>
</component>
<idbag name="PersistedSettings" table="OrganizationSetting" generic="true" lazy="false" inverse="false" cascade="save-update" >
<collection-id column="Id" type="int" >
<generator class="identity"/>
</collection-id>
<key column="OrganizationId" >
<column not-null="false" name="OrganizationId" />
</key>
<composite-element class="Cutter.Domain.Membership.Setting, Cutter">
<property column="SettingValue" name="Value"/>
<many-to-one class="Cutter.Domain.Membership.SettingDefinition" column="SettingId" name="Definition" cascade="none"/>
</composite-element>
</idbag>
What the code here is doing is building up an Organization and I'm creating new Setting objects. The SettingDefinition is a mutable persisted object which my code is pulling in so essentially we have:
Code:
Organization org=new Organization(){initilizers....};
SettingDefinition def=settingDao.GetSetting("MySetting");
org.Settings.Add(new Setting(def){Value="SomeValue"});
orgDao.SaveOrUpdate(org);
The confusing piece is that this works fine in my unit tests but in some production code is where it is failing which is essentially doign the same thing.
The other thing is this code is within a loop. I am creating many organizations, and the first three or four have no issues. Then it fails.
However, I don't understand why nHibernate would be pulling System.Object for the id of an element of an idBag. Any thoughts or ideas?
Thanks,
Josh