gpt4 book ai didi

nhibernate - 具有相同标识符值的不同对象已与 session + nhibernate 相关联

转载 作者:行者123 更新时间:2023-12-02 02:20:01 25 4
gpt4 key购买 nike

我正在使用 ninject mvc 3 和 nhibernate,当我尝试进行更新时出现此错误,我不明白为什么。

NHibernate.NonUniqueObjectException was unhandled by user code
Message=a different object with the same identifier value was already associated with the session: e1a7bd1f-fe1d-4c2e-a459-9fcb0106ad1d, of entity: Card
Source=NHibernate
EntityName=Card
StackTrace:
at NHibernate.Engine.StatefulPersistenceContext.CheckUniqueness(EntityKey key, Object obj)
at NHibernate.Event.Default.DefaultSaveOrUpdateEventListener.PerformUpdate(SaveOrUpdateEvent event, Object entity, IEntityPersister persister)
at NHibernate.Event.Default.DefaultSaveOrUpdateEventListener.EntityIsDetached(SaveOrUpdateEvent event)
at NHibernate.Event.Default.DefaultUpdateEventListener.PerformSaveOrUpdate(SaveOrUpdateEvent event)
at NHibernate.Event.Default.DefaultSaveOrUpdateEventListener.OnSaveOrUpdate(SaveOrUpdateEvent event)
at NHibernate.Impl.SessionImpl.FireUpdate(SaveOrUpdateEvent event)
at NHibernate.Impl.SessionImpl.Update(Object obj)
at CCRecomendator.Framework.Data.Repository.NhibernateRepo.Update[T](T entity) in NhibernateRepo.cs:line 33
at CardService.EditCard(Card card, IList`1 rewardTiersToUseAfterCap) in CardService.cs:line 108
at
CardController.EditCbCreditCard(CbCreditCardFrmVm vm) in CardController.cs:line 505
at lambda_method(Closure , ControllerBase , Object[] )
at System.Web.Mvc.ActionMethodDispatcher.Execute(ControllerBase controller, Object[] parameters)
at System.Web.Mvc.ReflectedActionDescriptor.Execute(ControllerContext controllerContext, IDictionary`2 parameters)
at System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary`2 parameters)
at System.Web.Mvc.ControllerActionInvoker.<>c__DisplayClass15.<InvokeActionMethodWithFilters>b__12()
at System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodFilter(IActionFilter filter, ActionExecutingContext preContext, Func`1 continuation)
InnerException:

我不明白为什么它仍然在 nhibernate session 中。我有一个获取卡并将其绑定(bind)到 VM 的 Web 请求。

然后它显示在页面上。然后我有一个被调用的保存方法,我尝试将 VM 绑定(bind)到卡域,然后尝试更新它,这是当我收到上述错误时。

虽然这是 2 个不同的调用,但应该关闭 session 。

  Bind<ISessionFactory>().ToProvider<NhibernateSessionFactoryProvider>().InSingletonScope();
Bind<ISession>().ToMethod(context => context.Kernel.Get<ISessionFactory>().OpenSession()).InRequestScope();

我不确定我是否需要调用另一个 dispose 或什么。

我使用工作单元,所以我添加了一个 dispose 方法,但不确定何时调用它以及这是否能解决我的问题

public class UnitOfWork : IUnitOfWork, IDisposable
{
private ITransaction transaction;
private readonly ISession session;

public UnitOfWork(ISession session)
{
this.session = session;
session.FlushMode = FlushMode.Auto;
}

/// <summary>
/// Starts a transaction with the database. Uses IsolationLevel.ReadCommitted
/// </summary>
public void BeginTransaction()
{
transaction = session.BeginTransaction(IsolationLevel.ReadCommitted);
}

/// <summary>
/// starts a transaction with the database.
/// </summary>
/// <param name="level">IsolationLevel the transaction should run in.</param>
public void BeginTransaction(IsolationLevel level)
{
transaction = session.BeginTransaction(level);
}

private bool IsTransactionActive()
{
return transaction.IsActive;
}

/// <summary>
/// Commits the transaction and writes to the database.
/// </summary>
public void Commit()
{
// make sure a transaction was started before we try to commit.
if (!IsTransactionActive())
{
throw new InvalidOperationException("Oops! We don't have an active transaction. Did a rollback occur before this commit was triggered: "
+ transaction.WasRolledBack + " did a commit happen before this commit: " + transaction.WasCommitted);
}

transaction.Commit();
}

/// <summary>
/// Rollback any writes to the databases.
/// </summary>
public void Rollback()
{
if (IsTransactionActive())
{
transaction.Rollback();
}
}

public void Dispose() // don't know where to call this to see if it will solve my problem
{
if (session.IsOpen)
{
session.Close();
}

}


[HttpPost]
public ActionResult EditCbCard(CbCardFrmVm vm)
{
if (ModelState.IsValid)
{
Card card = new Card
{
Id = vm.Id, // id of the record in the database
Country = countryService.LoadCountryById(vm.SelectedCountry)
};

CardService.EditCard(card, rewardTiersToUseAfterCap);

}

ModelStateValidationWrapper wrapper = ConvertTo.ModelStateValidationWrapper(creditCardService.ValidationDictionary, ModelState);
return Json(wrapper);
}

public void EditCard(Card card, IList<string> rewardTiersToUseAfterCap)
{
try
{
unitOfWork.BeginTransaction();

nhibernateRepo.Update(creditCard);

unitOfWork.Commit();
}
catch (ADOException ex)
{
ErrorSignal.FromCurrentContext().Raise(ex);
ValidationDictionary.AddError("DbError", ExceptionMsgs.DbError);
unitOfWork.Rollback();
}
catch (SqlException ex)
{
ErrorSignal.FromCurrentContext().Raise(ex);
ValidationDictionary.AddError("DbError", ExceptionMsgs.DbError);
unitOfWork.Rollback();
}
}

任何人都明白为什么它会认为它在同一个 session 中。

最佳答案

即使您处置 session ,创建新卡片来更新状态也是不正确的。而不是

Card card = new Card
{
Id = vm.Id, // id of the record in the database
Country = countryService.LoadCountryById(vm.SelectedCountry)
};

使用

Card card = unitOfWork.Get<Card>(vm.Id)
card.Country = countryService.LoadCountryById(vm.SelectedCountry);

获取正确的状态。它会在不访问数据库的情况下为您提供缓存实例

关于nhibernate - 具有相同标识符值的不同对象已与 session + nhibernate 相关联,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8696753/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com