2010-09-18 12 views
7

Hl Guys,NHibernate.StaleStateException: recuento de filas inesperado: 0; esperado: 1

Estoy ocupado escribiendo un programa administrativo de back-end para un sistema que existe. Seleccioné NHibernate para mi solución de acceso a datos y soy bastante nuevo en esto. Tengo el siguiente error en una relación padre/hijo:

NHibernate.StaleStateException: Recuento de filas inesperado: 0; esperado: 1

Este error es causado por el hecho de que en mi código fuente agrego el nuevo objeto secundario en la colección secundaria de los padres de MeetingAdministrators. Cuando guardo el objeto principal, espero que también se agreguen los elementos secundarios, sin embargo, se genera un INSERT solo para el objeto primario. Nhibernate no genera un INSERT para el niño, sino que intenta ACTUALIZAR al niño aunque no exista. Por lo tanto, muestra el mensaje de error que se muestra arriba. He buscado en todas partes en la web y documentación de nhibernate para este escenario, pero no he encontrado ninguna ayuda. La mayoría de los códigos involucran claves externas que no son parte de la clave primaria, o las personas parecen estar lidiando con relaciones de uno a uno o de muchos a muchos. Necesito especificar el mapeo y el código para que al insertar el padre, los niños se inserten también. Por favor ayuda.

Mi estructura de datos es el siguiente:

Reunión - tabla primaria

  • MeetingID (pk) (int, identidad)
  • Descripción
  • StartDate
  • IsActive
  • Lugar

MeetingAdministrator - tabla secundaria

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

Y aquí es la de Visual Basic. Fuente de red:

<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 

Éstos son los archivos de asignación:

<!-- 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> 

Respuesta

6

Estoy bastante seguro de que tendrá que añadir una propiedad a su clase <version/>MeetingAdministrator tener este trabajo propertly. Ver this article para mayor discusión.

+0

Gracias a un millón de Dan, Eso funcionó. Seguí el artículo y también agregué cosas como el método Equals en lugar de lo que estaba haciendo, que es anular igual y dejar la implementación base allí. Pero fue la propiedad que funcionó. Es extraño pensar que hay tan poca información clara sobre esta etiqueta por ahí – Tachi

+0

@Tachi - asegúrese de anular también GetHashCode; esto es importante si va a mapear s por ejemplo ... ¡me alegra poder ayudar! – DanP

+0

su enlace está desafortunadamente muerto; ( –

7

Obtuvo el mismo mensaje de error pero fue desencadenado por una eliminación. La razón simple era que la entrada ya había sido borrada.

+2

También he tenido este mismo problema. ¿Alguien sabe cómo prevenir con gracia la repetición de eliminación? – Kashif

+0

+1 Esto usualmente el problema conmigo. –

1

Para cualquier persona que tenga problemas con las inserciones con AutoNumber/AutoIncrement para MySQL, utilice la asignación. Encontré que el.La identidad puede ser temperamental

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