Question

Je développe une application web ASP.NET MVC sous .NET 3.5, NHibernate et hébergée sur Windows Azure.Lorsque l'application Web est exécutée à partir de la structure de développement locale, elle fonctionne correctement.Pourtant, lorsque je le déplace vers Windows Azure, chaque insertion effectuée à partir du rôle Web MVC se termine par l'exception répertoriée ci-dessous.

Avez-vous une idée de ce qui ne va pas avec ma logique NHibernate ?(peut-être la gestion de session, pas sûr)

[Échec de l'assertion :ID null dans Lokad.translate.entities.User Entrée (ne rincez pas la session après une exception)] nhibernate.event.default.defaultflushentityeventListener.checkid (objet Obj, ientityPersister Persister, objet ID, entityMode entitymode) +292 Nhibernate. Event.default.defaultFlushentityEventListener.getValues ​​(Entity, EntityEntry Entry, EntityMode EntityMode, Boolean Maybedirty, iSessionImplementorororor Session) +93 nhibernate.event.default.defaultFlushentityEventListener.Eplusheflult.Event.Eventfaulting Event) +158 NHHHIDE.Eventent.Eventefaulting. EventListener.flushentities ( FlushEvent event) +469 NHibernate.Event.Default.AbstractFlushingEventListener.FlushEverythingToExecutions(FlushEvent event) +339 NHibernate.Event.Default.DefaultFlushEventListener.OnFlush(FlushEvent event) +85 NHibernate.Impl.SessionImpl.Flush() +275 NHibernate.Transaction. Adotransaction.commit () +236 lokad.translate.repositories.pageRepository.create (page) lokad.translate.controllers.pagesController.Create (page Page) Lambda_Method (exécutionscope, contrôleur, objet []) +69 System.web.mvc .ReflectActionDescriptor.Execute (ControcerContext ControcerConText, idictionary2 parameters) +251 System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary2 paramètres) +31 System.web.mvc. <> C__displayClassa.b__7 () +88 System.web.mvc.ControllerActionInvoker.InvokeActionMethodFilter (Filter IaCectionFilter, ActionExecutingContex1 continuation) +534 System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodWithFilters(ControllerContext controllerContext, IList1 filtres, ActionDescriptor ActionDescriptor, iDictionary`2 Paramètres) +312 System.web.mvc.ControllerActionInvoker.InvokeAction (ContropleConText ControalerContext, String ActionName) +856 System.web.mvc.Controller.ExecUpecore () +185 System.web.mvc. Mvchandler.processRequest (httpContextBase httpContext) +221 System.web.callHandlereXecutionStep.system.web.httpapplication.iexecutionStep.Execute () Plus

Notez que j'utilise _session.FlushMode = FlushMode.Commit; et que le User est utilisé dans une coutume 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];
        }
    }
}
Était-ce utile?

La solution 2

J'ai enfin trouvé une solution à mon propre problème.Au cas où des gens seraient intéressés, je poste la solution ici.

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"};
        }
    }
}

Au fond, ce qui se passait, c'est que RoleProvider le référentiel ne semble pas avoir le même cycle de vie que les référentiels classiques en vue/dans le contrôleur.Par conséquent, au moment où le RoleProvider est appelé, la session NHibernate a déjà été supprimée, provoquant l'exception observée ci-dessus.

J'ai remplacé le code par le suivant ci-dessus.Celui-ci a sa propre gestion de session NHibernate et finit par fonctionner correctement.

Autres conseils

Vous ne devez jamais détecter les exceptions et les ignorer lors d'une transaction NHibernate.

J'essaie d'expliquer pourquoi.

Il peut y avoir des exceptions, causées par exemple par des contraintes dans la base de données.(Cela peut également être dû à des problèmes de mappage, à des exceptions levées par des propriétés ou à toute autre chose.) NHibernate essaie de synchroniser l'état en mémoire avec la base de données.Cela se fait lors de la validation - et parfois avant les requêtes pour s'assurer que les requêtes sont effectuées sur des données réelles.Lorsque cette synchronisation échoue, l'état dans la base de données est quelque chose de aléatoire, certaines modifications sont conservées, d'autres non.La seule chose que vous puissiez faire dans un tel cas est de fermer la session.

Considérez que les décisions et les calculs dans votre code sont basés sur des valeurs en mémoire.Mais - en cas d'exception ignorée, ces valeurs ne sont pas les valeurs de la base de données, elles n'y seront jamais.Ainsi, votre logique décidera et calculera sur des « données fantastiques ».

D'ailleurs, ce n'est jamais une bonne idée d'intercepter une exception (non typée) et de l'ignorer.Vous devez toujours connaître les exceptions que vous gérez et être sûr de pouvoir continuer.

Ce que vous faites ici, c'est avaler des erreurs de programmation.Croyez-moi, le système ne sera pas plus stable.La question est seulement :remarquez-vous l'erreur lorsqu'elle se produit, ou l'ignorez-vous là-bas et même conserver le résultat de l'erreur dans la base de données?Lorsque vous effectuez cette dernière opération, vous n'avez pas à être surpris lorsque votre base de données est incohérente et que d'autres erreurs surviennent lorsque vous essayez d'obtenir les données de la base de données.Et vous ne trouverez jamais le code qui est la véritable cause de l’erreur.

Cette exception peut se produire si les noms de vos colonnes incluent des mots réservés (par ex.utilisez status comme nom de colonne et il deviendra impossible de sauvegarder)

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top