c# asp.net nhibernate nhibernate-mapping spring.net

c# - NHibernate: la combinación en cascada de las entidades secundarias falla para la entidad principal desconectada



asp.net nhibernate-mapping (1)

cada entidad con una Id. válida se ve como persistente, por eso intenta actualizarla en la combinación pero porque aún no se ha guardado, falla. Llame a session.Flush() después de session.Update()

Enfoque actual

En una aplicación de formularios web de ASP.NET (utilizando Spring.NET y NHibernate) tenemos una raíz agregada ( Persona ) cuyos detalles se capturan en varias pantallas / páginas. La entidad de persona existe antes de entrar en este flujo de trabajo, y todos los cambios realizados en el gráfico de objetos de persona son atómicos, por lo que solo deben vaciarse a la base de datos al enviar la pantalla final.

Para lograr esto, cargamos la Persona (perezosamente) desde la base de datos usando NHibernate 3.2 la primera vez en la primera página, y luego cargamos y guardamos el gráfico del objeto Person serializado en una variable de Sesión HTTP a medida que avanzamos en la página a través del proceso.

Después de recuperar a la Persona de la sesión HTTP, se encuentra en un estado separado de la sesión actual de NHibernate, por lo que volvemos a adjuntar invocando el método Update () en la sesión actual, de esta manera:

var sessionPerson = Session[PersonSessionName] as Person; var currentSession = SessionFactory.GetCurrentSession(); currentSession.Update(sessionPerson);

Nota: Usar Lock () lanzó una excepción, advirtiendo que el "objeto reasociado tiene una colección sucia".

Cuando se vuelve a unir, podemos recorrer el gráfico de objetos como se esperaba, extrayendo datos de la base de datos para entidades secundarias que aún no se habían cargado en la memoria.

Subconjunto de archivos de mapeo

<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" auto-import="false" assembly="Domain" namespace=" TestApp.Domain"> <class name="Person" table="Person"> <id name="Id"> <generator class="TestApp.CustomNHibernateHiLoGenerator, TestApp.Core" /> </id> <property name="Name" not-null="false" /> <bag name="PersonCountries" access="field.camelcase-underscore" cascade="all-delete-orphan"> <key column="PersonId" foreign-key="FK_ PersonCountry_Person" not-null="true" /> <one-to-many class="PersonCountry" /> </bag> </class> <class name="Country" table="Country"> <id name="Id"> <generator class="TestApp.CustomNHibernateHiLoGenerator, TestApp.Core" /> </id> ... No back reference to Person </class> </hibernate-mapping>

Dominio

public class PersonCountry : Entity, ICloneable { // No properties of note } public class Person : Entity, ICloneable { public virtual string Name { get; set; } public virtual IEnumerable<PersonCountry> PersonCountries { get; set; } ... // More Properties }

Flushing cambios a la base de datos

.. // Code-behind PricingService.Save(ProductContext.Pricing, forceMerge: true); public class PricingService : IPricingService { [Transaction] // Spring.NET transaction public Pricing Save(Pricing pricing, bool forceMerge = false) { if(forceMerge) { CurrentSession.Merge(entity); } else { CurrentSession.SaveOrUpdate(entity); } } }

Cuando llega el momento de vaciar todos los cambios en la base de datos, siempre que solo cambiemos Nombre , el cambio funciona como se esperaba. Sin embargo, agregar un nuevo elemento de País a Persona hace que la conexión en cascada de Merge () en relaciones de uno a varios falle con la siguiente excepción (extrañamente, eliminar un país funciona bien).

NHibernate.StaleStateException: Batch update returned unexpected row count from update; actual row count: 0; Expected: 1

Cualquier ayuda sería muy apreciada.