Pregunta

Estoy desarrollando una aplicación web ASP.NET MVC en .NET 3.5, NHibernate y alojada en Windows Azure.Cuando la aplicación web se ejecuta desde el tejido de desarrollo local, funciona bien.Sin embargo, cuando lo muevo a Windows Azure, cada inserción realizada desde el rol web MVC termina con la excepción que se detalla a continuación.

¿Alguna idea de qué hay de malo en mi lógica de NHibernate?(podría ser la gestión de la sesión, no estoy seguro)

[Error de afirmación:ID NULL en lokad.translate.entities.user Entrada (no se enjuague la sesión después de que ocurra una excepción)] nHibernate.event.default.defaultflushEntityEventListener.Checkid (Obj OBJ, IentityPersister Persister, Object Id, EntityMode EntityMode) +292 Nhibernate. Event.default.defaultflushEntityEventListener.getValues ​​(Entidad de objeto, entrada EntityEntry, EntityMode EntityMode, Boolean MightBedIrty, ISessionImplementer Session) +93 nHibernate.event.default.DefaultEntityEventListener.onflushEntity (Evento FlushEntityEvent) +158 ushingeventListener.flushentities ( Evento FLUSHEVENT) +469 nHibernate.event.default.abstractflushingEventListener.flusheververythingtoExecutions (Flushevent Event) +339 nHibernate.event.deffault.defeflusheventListener.on . AdoTransaction.ComMit () +236 lokad.translate.Repositories.PagePository.Create (página de página) lokad.translate.controllers.pagesController.create (página de página) lambda_method (ejecutionscope, controlerBase, objeto []) +69 system.web.mvc .ReflectedActionDescriptor.Execute(ControllerContext controllerContext, IDictionary2 parameters) +251 System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary2 parámetros) +31 System.web.mvc. <> C__displayclassa.b__7 () +88 System.web.mvc.ControllerActionInvoker.invokeActionMethodFilter (FILTER IACTIONFILTER, ActionExecutingContex1 continuation) +534 System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodWithFilters(ControllerContext controllerContext, IList1 Filtros, ActionDescriptor ActionDescriptor, Idictionary`2 Parámetros) +312 System.Web.MVC.ControllerActionInvoker.InvokeAction (ControllerContext ControllerContext, String ActionName) +856 System.Web.MVC.Controller.executecore () +185 System.Web.MVC. Mvchandler.processRequest (httpContextBase httpContext) +221 system.web.callhandlerExecutionstep.system.web.httpapplication.iexecutionstep.ExExeCute () +586 system.web.httpapplication.executep (iexecutionstep step.

Tenga en cuenta que estoy usando _session.FlushMode = FlushMode.Commit; y que el User se utiliza en una costumbre RoleProvider

public class SimpleRoleProvider : RoleProvider 
{
    readonly UserRepository Users = new UserRepository();

    public override string[] GetRolesForUser(string username)
    {
        try
        {
            var user = Users.Get(username);

            // no role if user is not registered
            if (null == user) return new string[0];

            // default role for registered user
            return user.IsManager ? new[] { "Manager", "User" } : new[] { "User" };
        }
        catch (Exception)
        {
            // role should not fail in case of DB issue.
            return new string[0];
        }
    }
}
¿Fue útil?

Solución 2

Finalmente encontré una solución a mi propio problema. En caso de que la gente esté interesada, estoy publicando la solución aquí.

public class SimpleRoleProvider : RoleProvider 
{
    // isolated session management for the RoleProvider to avoid
    // issues with automated management of session lifecycle.

    public override string[] GetRolesForUser(string username)
    {
        using (var session = GlobalSetup.SessionFactory.OpenSession())
        {
            var users = new UserRepository(session);
            var user = users.Get(username);

            // no role if user is not registered
            if (null == user) return new string[0];

            // default role for registered user
            return user.IsManager ? new[] {"Manager", "User"} : new[] {"User"};
        }
    }
}

Básicamente, lo que sucedía es que el repositorio RoleProvider no parece tener el mismo ciclo de vida que los repositorios normales en vista / en el controlador. Como resultado, en el momento en que se llama a RoleProvider, la sesión de NHibernate ya se ha eliminado, lo que causa la excepción observada aquí anteriormente.

He reemplazado el código por el siguiente aquí arriba. Este tiene su propia administración de sesión de NHibernate, y termina funcionando bien.

Otros consejos

Nunca debe detectar excepciones e ignorarlas durante una transacción de NHibernate.

Intento explicar por qué.

Podría haber excepciones, por ejemplo, causadas por restricciones en la base de datos. (también podría ser causado por problemas de mapeo, excepciones generadas por propiedades o cualquier otra cosa). NHibernate intenta sincronizar el estado en la memoria con la base de datos. Esto se realiza en commit, y a veces antes de las consultas para asegurarse de que las consultas se realicen con datos reales. Cuando esta sincronización falla, el estado en la base de datos es algo aleatorio , algunos cambios persisten, otros no. Lo único que puede hacer en ese caso es cerrar la sesión.

Tenga en cuenta que las decisiones y los cálculos en su código se basan en valores en la memoria . Pero, en caso de una excepción ignorada, estos valores no son los valores de la base de datos, nunca estarán allí. Entonces su lógica decidirá y calculará sobre 'datos de fantasía'.

Por cierto, nunca es una buena idea detectar ninguna excepción (sin tipo) e ignorarla . Siempre debe conocer las excepciones que maneja y asegurarse de poder continuar.

Lo que estás haciendo aquí es tragar errores de programación. Créame, el sistema no será más estable. La pregunta es solo: ¿notas el error cuando ocurre o lo ignoras allí e incluso persiste el resultado del error en la base de datos ? Cuando hace esto último, no tiene que sorprenderse cuando su base de datos es inconsistente y surgen otros errores cuando intenta obtener los datos de la base de datos. Y nunca encontrará el código que es la causa real del error.

Esta excepción puede ocurrir si los nombres de sus columnas incluyen palabras reservadas (por ejemplo, use el estado como un nombre de columna y será imposible guardar)

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top