|
|
|
I'm attaching a patch against the trunk (rev 3075) for the changes described in this issue. The changes include:
AbstractEntityPersister.cs 2299:2304 -- Added logic in Insert() to assume the custom sql string (if available) will return the identity id. 2815:2820 -- Added logic in PostInstantiate() to treat the resultset of the custom sql string just like it would for a normal NHibernate.Test.SqlTest: IdentityInsertWithStoredProcsTest.cs -- Abstract test case for use with many dialects MSSQLIdentityInsertWithStoredProcsTest.cs -- MS SQL Server dialect derivative of IdentityInsertWithStoredProcsTest MSSQLIdentityInsertWithStoredProcs.hbm.xml -- Mapping file for use in MSSQLIdentityInsertWithStoredProcsTest All tests continue to pass with this fix, which seems to indicate that Sam Ritchie's concerns are not applicable. Thanks!!! Hi!
I was trying NHibernate 2.0 beta with stored procedures and I still have issues with sql-insert and identity in SQL Server (2000 and 2005). No matter what script I specify in <sql-string>, SqlServer throws "Parameterized Query '(@p0 int,@p1 nvarchar(7),@p2 int)exec InsertTest @p0, @p1' expects parameter @p2, which was not supplied." The query is: exec sp_executesql N'exec InsertTest @p0, @p1',N'@p0 int,@p1 nvarchar(4),@p2 int',@p0=342,@p1=N'test',@p2=default The entity has 2 properties and the Id. I tried to pass a dummy parameter @id to the stored procedure but I still get the same error: exec sp_executesql N'exec InsertTest @p0, @p1, @p2',N'@p0 int,@p1 nvarchar(4),@p2 int',@p0=342,@p1=N'test',@p2=default It seems like the problem is in the @p2=default part (I tried in the query analyzer to excute any kind of script passing default to a parameter and it breaks). When I remove this parameter or replace the value to 0 or something (but not 'default'), it works. Thanks!! In my case I am using a View in SQLServer 2000 for querying and stored procedures for inserting data.
When I try to use Id generator as "identity" instead of using the stored procedure for insert, the application is trying to update the View directly. I had to change a little the code Sam Ritchie posted ... In this piece ... if (customSQLInsert[0] != null) { // Assume the custom insert sql already contains an identity select statement insertSelectSQL = sql.Text; } ... I had to change this if (customSQLInsert[0] != null) { // Assume the custom insert sql already contains an identity select statement insertSelectSQL = customSQLInsert[0]; // I had to change this for making it work. } otherwise it will be taking the default sql and will attempt to insert data into the view. And if a custom sql has been specified it should be correct to use this instead of the default sql that Nhibernate generates. Thanks Thanks to James Nail to refresh the situation of this issue in nhusers maling-list.
|
|||||||||||||||||||||||||||||||||||||||||||
I've most likely broken something important (in particular, I haven't tested this with multiple table enitites yet), but I'm listing my code changes below in case they're useful.
in AbstractEntityPersister.PostInstantiate():
SqlCommandInfo defaultIdentityInsert = GenerateIdentityInsertString(PropertyInsertability);
sqlIdentityInsertString = customSQLInsert[0] == null
? defaultIdentityInsert
: new SqlCommandInfo(customSQLInsert[0], defaultIdentityInsert.ParameterTypes);
in AbstractEntityPersister.Insert(object[], bool[], SqlCommandInfo, object, ISessionImplementor):
if (customSQLInsert[0] != null)
{
// Assume the custom insert sql already contains an identity select statement
insertSelectSQL = sql.Text;
}
else if (sql.CommandType == CommandType.Text)
{
insertSelectSQL = Dialect.AddIdentitySelectToInsert(sql.Text, IdentifierColumnNames[0], TableName);
}