2010-09-18 10 views
7

Hl Guys,NHibernate.StaleStateException: Conteggio righe imprevisto: 0; previsto: 1

Sono impegnato a scrivere un programma amministrativo di backend per un sistema esistente. Ho scelto NHibernate per la mia soluzione di accesso ai dati e sono abbastanza nuovo per questo. Sto riscontrando il seguente errore in una relazione genitore/figlio:

NHibernate.StaleStateException: Conteggio righe inatteso: 0; previsto: 1

Questo errore è causato dal fatto che nel mio codice sorgente aggiungo il nuovo oggetto figlio alla raccolta figli del genitore di MeetingAdministrators. Quando salvi l'oggetto genitore, mi aspetto che vengano aggiunti anche i bambini, tuttavia un INSERT viene generato solo per l'oggetto padre. Nhibernate non genera un INSERT per il bambino ma tenta invece di AGGIORNARE il bambino anche se non esiste. Quindi visualizza il messaggio di errore mostrato sopra. Ho guardato dappertutto sul web e la documentazione di Nhibernate per questo scenario ma non ho trovato alcun aiuto. La maggior parte del codice coinvolge chiavi esterne che non fanno parte della chiave primaria, o le persone sembrano avere a che fare con relazioni uno a uno o molti a molti. Ho bisogno di specificare la mappatura e il codice in modo che sull'inserimento del genitore vengano inseriti anche i figli. Per favore aiuto.

La mia struttura dati è la seguente:

Meeting - tabella padre

  • MeetingID (PK) (int, identità)
  • Descrizione
  • DataInizio
  • IsActive
  • Venue

MeetingAdministrator - tabella figlio

  • MeetingID (pk, fk)
  • AdminNetworkID (PK) (varchar)
  • DateCreated
  • IsActive

E qui è il Visual Basic. Fonte NET:

<Serializable()> _ 
Public Class MeetingAdministrator 

    Private _MeetingID As Integer 
    Public Overridable Property MeetingID() As Integer 
     Get 
      Return _MeetingID 
     End Get 
     Set(ByVal value As Integer) 
      _MeetingID = value 
     End Set 
    End Property 

    Private _AdminNetworkID As String 
    Public Overridable Property AdminNetworkID() As String 
     Get 
      Return _AdminNetworkID 
     End Get 
     Set(ByVal value As String) 
      _AdminNetworkID = value 
     End Set 
    End Property 

    Private _IsActive As Byte 
    Public Overridable Property IsActive() As Byte 
     Get 
      Return _IsActive 
     End Get 
     Set(ByVal value As Byte) 
      _IsActive = value 
     End Set 
    End Property 

    Private _DateCreated As Date 
    Public Overridable Property DateCreated() As Date 
     Get 
      Return _DateCreated 
     End Get 
     Set(ByVal value As Date) 
      _DateCreated = value 
     End Set 
    End Property 

    Private _LastModified As Date 
    Public Overridable Property LastModified() As Date 
     Get 
      Return _LastModified 
     End Get 
     Set(ByVal value As Date) 
      _LastModified = value 
     End Set 
    End Property 

    Private _meeting As Meeting 
    Public Overridable Property Meeting() As Meeting 
     Get 
      Return _meeting 
     End Get 
     Set(ByVal value As Meeting) 
      _meeting = value 
     End Set 
    End Property 

    Public Overrides Function Equals(ByVal obj As Object) As Boolean 
     Return MyBase.Equals(obj) 
    End Function 

    Public Overrides Function GetHashCode() As Integer 
     Return MyBase.GetHashCode() 
    End Function 

End Class 




Imports Iesi.Collections 
Imports Iesi.Collections.Generic 



Public Class Meeting 

    Private _MeetingID As Integer 
    Private _Description As String 

    Public Overridable Property MeetingID() As Integer 
     Get 
      Return _MeetingID 
     End Get 
     Set(ByVal value As Integer) 
      _MeetingID = value 
     End Set 
    End Property 

    Public Overridable Property Description() As String 
     Get 
      Return _Description 
     End Get 
     Set(ByVal value As String) 
      _Description = value 
     End Set 
    End Property 

    Private _StartDate As Date = Now 
    Public Overridable Property StartDate() As Date 
     Get 
      Return _StartDate 
     End Get 
     Set(ByVal value As Date) 
      _StartDate = value 
     End Set 
    End Property 

    Private _IsActive As Byte 
    Public Overridable Property IsActive() As Byte 
     Get 
      Return _IsActive 
     End Get 
     Set(ByVal value As Byte) 
      _IsActive = value 
     End Set 
    End Property 

    Private _DateCreated As Date 
    Public Overridable Property DateCreated() As Date 
     Get 
      Return _DateCreated 
     End Get 
     Set(ByVal value As Date) 
      _DateCreated = value 
     End Set 
    End Property 

    Private _Venue As String 
    Public Overridable Property Venue() As String 
     Get 
      Return _ Venue 
     End Get 
     Set(ByVal value As String) 
      _ Venue = value 
     End Set 
    End Property 

    Private _meetingAdministrator As ISet(Of MeetingAdministrator) 
    Public Overridable Property MeetingAdministrators() As ISet(Of MeetingAdministrator) 
     Get 

      Return _meetingAdministrator 
     End Get 
     Set(ByVal value As ISet(Of MeetingAdministrator)) 
      _meetingAdministrator = value 
     End Set 
    End Property 

    Public Overridable Sub AddAdministrator(ByVal meetingAdministrator As MeetingAdministrator) 
     meetingAdministrator.Meeting = Me 

     _meetingAdministrator.Add(meetingAdministrator) 
    End Sub 


    Public Sub New() 
     _meetingAdministrator = New HashedSet(Of MeetingAdministrator)() 

    End Sub 
End Class 

Qui ci sono i file di mapping:

<!-- Meeting.hbm.xml --> 
<?xml version="1.0" encoding="utf-8" ?> 
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="Data" 
        namespace="Data.Domain" > 

    <!-- Mapping Information --> 
    <class name="Meeting" table="Meeting" > 
    <id name="MeetingID" column="MeetingID" type="int"> 
     <generator class="identity" /> 
    </id> 
    <property name="Description" /> 
    <property name="StartDate" /> 
    <property name="IsActive" /> 
    <property name="Venue" /> 
    <set name="MeetingAdministrators" table="MeetingAdministrator" inverse="true" lazy="true" cascade="save-update" access="property" > 
     <key column="MeetingID" foreign-key="MeetingID" /> 
     <one-to-many class="Meeting" /> 
    </set> 
    </class> 
</hibernate-mapping> 

<!-- MeetingAdministrator.hbm.xml --> 
<?xml version="1.0" encoding="utf-8" ?> 
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="Data" 
        namespace="Data.Domain" > 

    <!-- Mapping Information --> 
    <class name="MeetingAdministrator" table="MeetingAdministrator" > 
    <composite-id> 
     <key-property name="AdminNetworkID" column="AdminNetworkID" type="string" > 
     </key-property> 
     <key-many-to-one name="Meeting" class="Meeting" > 
     <column name="MeetingID" /> 
     </key-many-to-one> 
    </composite-id> 
    <property name="IsActive" /> 
    <property name="DateCreated" /> 
    </class> 
</hibernate-mapping> 

risposta

6

Sono abbastanza sicuro che è necessario aggiungere una proprietà <version/> alla classe MeetingAdministrator di avere questo lavoro propertly. Vedi this article per ulteriori discussioni.

+0

Grazie a un milione di Dan, ha funzionato. Ho seguito l'articolo e aggiunto anche cose come il metodo Equals rispetto a quello che stavo facendo, che è override equals e lascia lì l'implementazione di base. Ma era la proprietà che funzionava. È strano pensare che ci siano così poche informazioni chiare su questo tag là fuori – Tachi

+0

@Tachi - assicuratevi di sovrascrivere anche GetHashCode; questo è importante se per esempio stai mappando ... felice di poterti aiutare! – DanP

+0

il tuo link è sfortunatamente guasto ( –

7

Ottenuto lo stesso messaggio di errore ma è stato attivato da un'eliminazione. La semplice ragione era che la voce era già stata cancellata.

+2

Ho anche avuto lo stesso esatto problema Qualcuno sa come impedire con grazia la cancellazione ripetuta? – Kashif

+0

+1 Questo di solito è il problema con me. –

1

Per chi ha problemi con gli inserimenti con numero automatico/AutoIncrement per MySQL utilizzare la mappatura. Ho trovato che il.L'identità può essere temperamentale

Id(x => x.Id).GeneratedBy.Increment();