NHibernate无状态会话 - 由于引用属性而无法加载,更新和保存对象

时间:2013-08-15 12:35:49

标签: c# nhibernate

我正在研究一些使用NHibernate进行一些中等重度数据处理的代码(是的,我知道,也许这不是真正适合这项工作的工具。但这是我必须要处理的事情)

我使用无状态会话来获取前1000个对象,检查,更新并在需要时将它们添加到更新对象列表中。 然后我重复接下来的1000个对象,直到我完成。下面是代码的一个显着简化版本。

List<MarketOrder> updated = new List<MarketOrder>();
IStatelessSession session = SessionProvider();
int offset = 0;
bool moreToGet = true;

while (moreToGet)
{
    var result = session.Query<MarketOrder>().Where(o => o.Owner.ID == currentEntityID && !o.Updated);
    var tmp = result.Skip(offset).Take(1000);

    foreach (MarketOrder item in data) 
    { 
        notUpdated.OrderState = MarketOrderState.Closed;
        updated.Add(notUpdated);
    }

    if (data.Count == pageSize) { offset += pageSize; }
    else { moreToGet = false; }
}

然后打开另一个无状态会话以进行批量更新

IStatelessSession session = SessionProvider();
foreach (MarketOrder o in updated) { session.Update(o); }

当我运行单元测试时,出现错误:

Test 'TestProcess_AutoCloseOrder' failed: NHibernate.PropertyValueException : Error         dehydrating property value for Data.Models.MarketOrder.Owner
---- NHibernate.PropertyAccessException : Exception occurred getter of Common.Models.ModelBase.Version
-------- System.Reflection.TargetInvocationException : Exception has been thrown by the target of an invocation.
------------ NHibernate.SessionException : proxies cannot be fetched by a stateless session

经过一番捣乱之后,我认为错误是因为,在更新中,NHibernate试图访问正在保存的Owner的{​​{1}}属性。 (我假设这是级联更新) MarketOrder填充了代理,因为它是从无状态会话加载的,所以无法访问。

果然,如果我从常规会话加载而不是无状态会话,那么一切正常。该解决方案将导致生产中的性能损失,但我宁愿避免它。

我可以将Owner设置为不延迟加载,但对于所有类似的情况,这不是一个实用的解决方案。

这个问题的答案:NHibernate: proxies cannot be fetched by a stateless session error message。建议将问题属性作为初始加载的一部分来获取,但这看起来非常浪费。我只想更新主对象上的一些属性,为什么我还要加载所有对象的子引用?

我想要的是NHibernate意识到只有主Owner对象发生了变化,而且没有费心将更新级联到MarketOrder。事实上,现在我考虑一下,我认为无状态会话本来应该是级联更新吗?

所以任何人都知道这里发生了什么以及如何解决它?

0 个答案:

没有答案