2011-11-01 25 views
6

sto scrivendo progetto e utilizzando NHibernate 3.1Perché NHibernate lancia "StaleObjectStateException"?

SimpleTest:

Forum forum = Session.CreateCriteria<Forum>().Add(Restrictions.Eq("UrlName", "reportabug")).UniqueResult<Forum>(); 
forum.TopicsCount++; 
IForumRepository forumRepository = new ForumRepository(SessionFactory); 
forumRepository.Update(forum); 

public virtual void Update(TEntity entity) 
{ 
    if (!session.Transaction.IsActive) 
    { 
     TResult result; 
     using (var tx = session.BeginTransaction()) 
     { 
      session.SaveOrUpdate(entity) 
      tx.Commit(); 
     } 
     return result; 
    } 
    session.SaveOrUpdate(entity) 
} 

L'ultimo aggiornamento lancia un'eccezione: interrogazione

StaleObjectStateException was unhandled by user code: 
    Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect) 

SQL:

UPDATE Forums 
SET Name = 'Forums Issues (not product support)' /* @p0 */, 
     UrlName = 'reportabug' /* @p1 */, 
     Description = 'Use this forum to report issues with the online forums application. When reporting an issue please include relevant details such as repro steps, error messages and browser version.' /* @p2 */, 
     CategoryId = 'b2cc232c-0d5c-4f35-bb6f-29c67d7d40c2' /* @p3 */, 
     TopicsCount = 1 /* @p4 */ 
WHERE ForumId = '864046b7-ca57-48c4-8a81-082103223527' /* @p5 */ 

ForumId è corretta. Forse questa è la concorrenza? Hai qualche idea?

+0

@ManuPK, l'eccezione viene generata sulla riga tx.Commit(); –

risposta

5

StaleObjectStateException è un modo di ibernazione per garantire la coerenza dei dati leggere l'API here. Hibernate mantiene lo version di oggetti che aggiorna e genera un errore se la versione nel DB e nella memoria non corrisponde. Maggiori informazioni sul meccanismo di blocco ottimistico here.

Quindi, eseguire il debug dell'applicazione con queste informazioni. Non ho familiarità con la sintassi C# ma penso che il secondo salvataggio dovrebbe essere nella condizione else.

+0

Questo è corretto, mi mancava totalmente questo: P +1. @Kovpaev - Rimuove l'ultimo 'session.SaveOrUpdate (entity)', non ce n'è bisogno. –

+0

@Ash Burlaczenko, la chiamata alla fine del metodo è necessaria se il metodo Update() viene richiamato nel contesto della transazione esterna. In caso contrario, viene creato nel blocco "se". –

Problemi correlati