2013-05-19 5 views
0

У меня есть NHibernate отображение-на-код, который работает при использовании стандартной ВСТАВКИ на стандартном SQLInsertОшибка при использовании пользовательской функции на NHibernate отображение-на-кодового SQLInsert

class ProductTranslationMapping : ClassMapping<ProductTranslation> 
{ 
    public ProductTranslationMapping() 
    { 
     . 
     . 
     SqlInsert ("insert into product_translation(product_id, language_code, product_name, product_description) values(?,?,?,?)"); 

     . 
     .  
    } 
} 

Однако я хочу использовать Postgresql хранимой процедуру , так как вставки и обновление могут использовать тот же самый рутинную

class ProductTranslationMapping : ClassMapping<ProductTranslation> 
{ 
    public ProductTranslationMapping() 
    { 

     .  
     . 
     SqlInsert ("select merge_product_translation(?,?,?,?)"); 
     SqlUpdate ("select merge_product_translation(?,?,?,?)"); 
     . 
     .  
    } 
} 

Однако, когда я использую Postgresql функции, то есть ошибка:

Unhandled Exception: 
NHibernate.StaleStateException: Unexpected row count: -1; expected: 1 
    at NHibernate.AdoNet.Expectations+BasicExpectation.VerifyOutcomeNonBatched (Int32 rowCount, IDbCommand statement) [0x00000] in <filename unknown>:0 
    at NHibernate.AdoNet.NonBatchingBatcher.AddToBatch (IExpectation expectation) [0x00000] in <filename unknown>:0 
    at NHibernate.Persister.Entity.AbstractEntityPersister.Insert (System.Object id, System.Object[] fields, System.Boolean[] notNull, Int32 j, NHibernate.SqlCommand.SqlCommandInfo sql, System.Object obj, ISessionImplementor session) [0x00000] in <filename unknown>:0 
[ERROR] FATAL UNHANDLED EXCEPTION: NHibernate.StaleStateException: Unexpected row count: -1; expected: 1 
    at NHibernate.AdoNet.Expectations+BasicExpectation.VerifyOutcomeNonBatched (Int32 rowCount, IDbCommand statement) [0x00000] in <filename unknown>:0 
    at NHibernate.AdoNet.NonBatchingBatcher.AddToBatch (IExpectation expectation) [0x00000] in <filename unknown>:0 
    at NHibernate.Persister.Entity.AbstractEntityPersister.Insert (System.Object id, System.Object[] fields, System.Boolean[] notNull, Int32 j, NHibernate.SqlCommand.SqlCommandInfo sql, System.Object obj, ISessionImplementor session) [0x00000] in <filename unknown>:0 

Если это поможет, вот мой Postgresql хранимую процедуру:

create or replace function merge_product_translation(p_product_id int, p_language_code text, p_product_name text, p_product_description text) returns int 
as 
$$ 
begin 
    if not exists(select * from product_translation where product_id = p_product_id and language_code = p_language_code) then  
     insert into product_translation(product_id, language_code, product_name, product_description) 
     values(p_product_id, p_language_code, p_product_name, p_product_description); 
    else   
     update product_translation set 
      product_name = p_product_name, 
      product_description = p_product_description 
     where product_id = p_product_id and language_code = p_language_code;  
    end if; 

    return 1; 

end; 
$$ 
language 'plpgsql'; 

Я также попытался следующие, но все-таки не повезло, все из них есть ошибка:

SqlInsert ("perform merge_product_translation(?,?,?,?)"); 
SqlInsert ("call merge_product_translation(?,?,?,?)"); 
SqlInsert ("{call merge_product_translation(?,?,?,?)}");   

Что я должен использовать поэтому я могу избежать ошибки unexpected row count of -1? Это также сложно для Google, поскольку google устраняет -1

ответ

1

NHibernate должен проверить результаты своих встроенных SQL-команд. То же самое требуется/применяется на вашем пользовательских реализации (хранимые процедуры), потому что он рассматривается одинаково.

Но есть хорошее решение. Подробнее здесь 17.3. Custom SQL for create, update and delete.

Экстракт:

The stored procedures are by default required to affect the same number of rows as NHibernate-generated SQL would. NHibernate uses IDbCommand.ExecuteNonQuery to retrieve the number of rows affected. This check can be disabled by using check="none" attribute in sql-insert element.

Решение: ... настроить отображение так:

<sql-insert check="none" >..</sql-insert> 
<sql-update check="none" >..</sql-update>