NHibernate:System.Argument异常:已添加具有相同键的项目

2024-01-10

我遇到了一个很难重现的偶发错误。我的第一个猜测是,不知怎的,我有一个泄漏的休眠会话,但是当我运行休眠分析器 http://nhprof.com/,我没有看到太多异常。

  • MVC 2.0
  • 流畅版本1.1.0.685
  • NHibernate 版本 2.1.2.4000

异常:System.ArgumentException: 具有相同密钥的项目已经 已添加。

堆栈跟踪:位于 System.Collections.Generic.Dictionary2.Insert(TKey key, TValue value, Boolean add) at NHibernate.Util.ThreadSafeDictionary2.添加(TKey 键,TValue 值)位于 NHibernate.SqlTypes.SqlTypeFactory.GetTypeWithLen[T](Int32 长度,TypeWithLenCreateDelegate 创建委托)在 NHibernate.Type.EnumStringType..ctor(类型 枚举类,Int32 长度)

我正在使用存储库模型。这是我的存储库类。

public sealed class Repository<T> : IRepository<T> where T : CoreObjectBase
{
    #region IRepository<T> Members

    private ISession Session
    {
        get
        {
            return new SessionHelper().GetSession();
        }
    }

    public IQueryable<T> GetAll()
    {
        return (from entity in Session.Linq<T>() select entity);
    }

    public T GetById(int id)
    {
        return Session.Get<T>(id);
    }

    public void Save(params T[] entities)
    {
        using (ITransaction tx = Session.BeginTransaction())
        {
            for (int x = 0; x < entities.Count(); x++)
            {
                var entity = entities[x];

                entity.Validate();

                Session.SaveOrUpdate(entities[x]);

                if (x == entities.Count() - 1 || (x != 0 && x % 20 == 0)) //20 is the batch size
                {
                    Session.Flush();
                    Session.Clear();
                }
            }
            tx.Commit();
        }
    }

    public void SaveWithDependence<K>(T entity, K dependant) where K : CoreObjectBase
    {
        entity.Validate();
        dependant.Validate();

        using (ITransaction tx = Session.BeginTransaction())
        {
            Session.SaveOrUpdate(entity);
            Session.SaveOrUpdate(dependant);
            tx.Commit();
        }
    }

    public void Save(T entity)
    {
        entity.Validate();

        using (ITransaction tx = Session.BeginTransaction())
        {
            Session.SaveOrUpdate(entity);
            tx.Commit();
        }
    }

    public void Delete(T entity)
    {
        using (ITransaction tx = Session.BeginTransaction())
        {
            Session.Delete(entity);
            tx.Commit();
        }
    }

    public T GetOne(QueryBase<T> query)
    {
        var result = query.SatisfyingElementFrom(Session.Linq<T>());

        return result;

        //return query.SatisfyingElementFrom(Session.Linq<T>());
    }

    public IQueryable<T> GetList(QueryBase<T> query)
    {
        return query.SatisfyingElementsFrom(Session.Linq<T>());
    }

    /// <summary>
    /// remove the sepcific object from level 1 cache so it can be refreshed from the database
    /// </summary>
    /// <param name="entity"></param>
    public void Evict(T entity)
    {
        Session.Evict(entity);
    }
    #endregion
}

这是我的会话助手,改编自this http://code.google.com/p/dot-net-reference-app/source/browse/trunk/src/Infrastructure/Impl/HybridSessionBuilder.cs.

public sealed class SessionHelper
{
    private static ISessionFactory _sessionFactory;
    private static ISession _currentSession;

    public ISession GetSession()
    {
        ISessionFactory factory = getSessionFactory();
        ISession session = getExistingOrNewSession(factory);
        return session;
    }

    private ISessionFactory getSessionFactory()
    {
        if (_sessionFactory == null)
        {
            _sessionFactory = BuildSessionFactory();
        }

        return _sessionFactory;
    }

    private ISessionFactory BuildSessionFactory()
    {
        return Fluently.Configure().Database(
            FluentNHibernate.Cfg.Db.MsSqlConfiguration.MsSql2005
                .ConnectionString(c => c
                    .FromConnectionStringWithKey("MyDatabase"))
                    .AdoNetBatchSize(20))
                .Mappings(m => m.FluentMappings.AddFromAssemblyOf<SessionHelper>())
                .BuildSessionFactory();
    }

    private ISession getExistingOrNewSession(ISessionFactory factory)
    {
        if (HttpContext.Current != null)
        {
            ISession session = GetExistingWebSession();
            if (session == null)
            {
                session = openSessionAndAddToContext(factory);
            }
            else if (!session.IsOpen)
            {
                session = openSessionAndAddToContext(factory);
            }

            return session;
        }

        if (_currentSession == null)
        {
            _currentSession = factory.OpenSession();
        }
        else if (!_currentSession.IsOpen)
        {
            _currentSession = factory.OpenSession();
        }

        return _currentSession;
    }

    public ISession GetExistingWebSession()
    {
        return HttpContext.Current.Items[GetType().FullName] as ISession;
    }

    private ISession openSessionAndAddToContext(ISessionFactory factory)
    {
        ISession session = factory.OpenSession();
        HttpContext.Current.Items.Remove(GetType().FullName);
        HttpContext.Current.Items.Add(GetType().FullName, session);
        return session;
    }
}

有什么想法或建议可以避免这个问题吗?


问题是,那SessionHelper不是线程安全的。它可能会构建多个会话工厂(这是单例的糟糕实现),这反过来可能会导致您看到的错误。

我建议使用夏普架构 http://www.sharparchitecture.net/作为指导。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

NHibernate:System.Argument异常:已添加具有相同键的项目 的相关文章

  • 随机 IIS 会话超时

    我有一个非常奇怪的问题 我正在寻求任何建议 我有一个运行在 IIS 6 上的 ASP NET 网站 它在大多数情况下运行良好 但是 会话似乎是随机清除的 因此 如果我登录 单击周围 我就会被随机启动 有时是在 30 秒 4 次点击之后 有时
  • OnPostAuthenticateRequest 中的 HttpContext.Current.Session 为 null

    这是一个n00b问题 也许你可以帮忙 当我在Application OnPostAuthenticateRequest事件 我无法查看Session since HttpContext Current Session一片空白 这是空的原因吗
  • NHibernate Session.Evict()

    我无法访问我面前的代码 所以我只是想知道是否有人可以帮助我解决 Session Evict 问题 假设我有一个包含地址子集合的 Person 对象 我从会话中填充 Person 对象并延迟加载 Addresses 集合 然后 我调用 Ses
  • 自动映射约定可以与映射覆盖一起使用吗?

    我的 id 有一个约定 它会自动映射名称为Id作为标识符 随着需求的充实 我需要调整域模型 所以很自然地我上网发现我需要创建一个继承自的类IAutoMappingOverride
  • 如何使用 C# 上传文件并将其保存到 Stream 以便进一步预览?

    有没有办法上传文件 将其保存到流中 该流我会将其临时保存在会话中 最后 我将尝试预览此会话中的此上传文件 例如 pdf 文件 Thanks EDITED 这就是我想做的 HttpPostedFileBase hpf Request File
  • 如何在 Nhibernate 中进行版本控制?

    我不敢相信让别人向我展示一个简单的工作示例是如此困难 这让我相信每个人都只能说得好像他们知道如何去做 但实际上他们并不知道 我将帖子缩短为仅我想要示例执行的操作 也许帖子太长了 吓跑了人们 为了获得这个赏金 我正在寻找一个可以在 VS 20
  • PHP - 按后退按钮时 Session_Destroy

    这是我的问题 我有一个名为login php 的登录页面 不包含HTML 代码 当用户正确输入其凭据时 他会被重定向到特定页面 在本例中我们将使用 test php 该页面上的唯一链接会注销当前会话 并将用户返回到index html 我的
  • 映射枚举列表

    我有一个名为 UserPermissions 的表 其中通过 userId 与用户表进行 FK 然后是一个用于枚举字符串值的字符串列 我看到的错误是 NHibernate MappingException 表 UserPermissions
  • NHibernate QueryOver<> - SubQuery 上的聚合函数

    如何使用 QueryOver 语法编写以下 SQL 语句 SELECT COUNT FROM SELECT FirstName LastName FROM People GROUP BY FirstName LastName as sub
  • NHibernate 二级缓存与 NHibernate Linq Provider 1.0

    如何使用 NHibernate Linq Provider 1 0 启用 NHibernate 二级缓存 二级缓存似乎仅适用于 ICriteria 使用 是的 我终于解决了这个问题 public IQuerable
  • NHibernate - 更新带有触发器的表会导致错误 - 意外行计数:2;预计:1

    因此 我尝试使用 NHibernate 更新 MS SQL 2005 数据库中的对象 请记住 这是许多实时系统中使用的旧数据库 我无法删除触发器 当我的数据提供程序尝试 SaveOrUpdate 一行时 我得到两个返回 一个用于实际更新 一
  • 场次抽奖

    有人能解释一下什么是会话扫彩票吗 我已附加 Laravel 框架的默认会话配置文件 问题 1 它说某些会话驱动程序必须manually扫荡他们的 存储位置 有人可以描述这个过程以及为什么会这样吗 必要的 哪些会话驱动程序需要此操作 2 为什
  • WebSphere 中跨 JVM 的会话复制

    我们建立了一个基础设施 其中网络服务器是集群的 而应用程序服务器不是 Web 服务器根据循环策略将请求路由到应用程序服务器 在这种情况下 一个应用程序服务器中可用的会话数据在另一应用程序服务器中不可用 无论如何 是否可以使来自第一个应用程序
  • 阻止注销页面后的后退按钮

    我有 php 注销页面 当用户单击注销链接时 请参阅此页面并重定向到索引页面 但是当单击后退按钮时 我会看到带有用户数据的上一页 当然 当我刷新页面时 我看不到以前的页面和数据 我在单击注销并单击后退按钮后检查了其他代码 drupal 但我
  • 使用 servicestack 如何防止 cookie 添加到响应中?

    我可以在事后删除cookie 方法如下 public override void Configure Funq Container container ResponseFilters Add req res dto gt HttpListe
  • PHP session_regenerate_id 和黑莓浏览器

    问候 我正在开发一个登录系统 并陷入了黑莓浏览器身份验证的困境 他们似乎对 PHP 的 session regenerate id 有问题 有人可以建议替代方案吗 以下是身份验证和登录脚本 UPDATE看来会话一般都不起作用 拿出 sess
  • Fluent Nhibernate 映射的单元测试

    我正在尝试了解社区的其他成员如何测试他们的 Fluent Nhibernate 映射 假设我有以下映射 public UserHeaderMap Table USER HEADER Id x gt x Id USER ID Map x gt
  • 会话cookie太大烧瓶应用程序[重复]

    这个问题在这里已经有答案了 我正在尝试使用会话 本地 加载某些数据 并且它已经工作了一段时间 但是现在我收到以下警告 并且不再加载通过会话加载的数据 b session cookie 太大 该值是 13083 字节 但是 标头需要 44 个
  • PHP 会话不适用于游戏

    我正在尝试模仿一款名为 SKUNK 用骰子玩 的游戏来完成一项作业 我无法让会话正常工作 这是我第一次使用 PHP 我还被告知无需会议即可完成 这是我的代码
  • Joomla getUser() 不显示更新的用户数据

    下面的代码允许我在用户的 Joomla 个人资料的个人资料页面中显示用户名 鉴于我已经覆盖了模板以获得我想要的外观和感觉 user JFactory getUser if user gt guest echo You are logged

随机推荐