我正在开发一个NHibernate项目,而且我之前在加载集合时遇到问题(http://stackoverflow.com/questions/4213506/c-hibernate-criteria-loading-collection),我现在在使用数据方面遇到了问题
我正在将C#与NHibernate和Spring.Net框架结合使用,在加载例如'ordercredit'之后,我获得了一个LazyInitializationException,然后访问了ordercredit的对象。
我使用此代码获取OrderCredit:
OrderCredit oc = CreditService.getOrderCredit(ordercredit.Id);
我用于加载的代码是使用DAO实现完成的:
[Transaction(TransactionPropagation.Required, ReadOnly = true)]
public OrderCredit GetOrderCredit(long ordercreditid)
{
var creditrules = Session.CreateCriteria(typeof(OrderCredit));
creditrules.Add(Restrictions.Eq("Id", ordercreditid));
return creditrules.List<OrderCredit>()[0];
}
当我在本地计算机上运行时,一切正常,我实际上打算加载那些'ordercredits'的列表,但那也出错了,所以我先尝试了一个更简单的步骤。
'OrderCredit'中的对象被定义为[OneToMany]。
当我把它放在testserver上,并尝试访问加载的OrderCredit的'OrderObject'对象时,我收到错误:
NHibernate.LazyInitializationException:正在初始化[.OrderObject#5496522] - 不能初始化代理 - 没有会话。
失败的代码:
Log.Debug(oc.OrderObject.Name);
有效的代码:
Log.Debug(oc.Id);
对于任何属于OrderCredit的对象,都会发生这种情况,但我可以访问OrderCredit的属性字段(例如OrderCredit.Id)。
此外,当我访问任何对象之前,我将数据返回到调用方法的原始函数,然后它会缓存信息,因此我可以访问它。
我已经阅读了很多关于这个问题的内容,比如关闭了Lazy,但这对我来说也不起作用(或者我在错误的地方做了那个)。
最令我失望的是,它实际上可以在我的本地计算机上运行,而不是在testserver上运行。我能做错什么?
非常感谢任何帮助。
第一次更新:
我现在正在使用GenericDao,使用加载1 ordercredit的默认方法。我使用以下代码通过Id加载1 ordercredit。
OrderCredit oc = GenericService.Load<OrderCredit>(Id);
GenericDAO中的代码如下,但它不会结束或中断会话,这意味着我可以访问附加到ordercredit的对象:
[Transaction(TransactionPropagation.Supports, ReadOnly = true)]
public T Load<T>(long id) where T : ISaveableObject
{
var obj = Session.Load<T>(id);
return obj;
}
这几乎与我在本期前面提到的函数中的代码相同。
我现在真的很困惑,因为我不知道结束会话会是什么。我会在它工作的时候使用它,但我想稍后更改它,所以我可以使用我的函数调用整个集合并通过每个循环访问它们。
目前,我使用我的'getOrderCredits'函数来获取OrderCredit对象的列表,并在foreach中获取Id,并使用GenericDao.Load获取实际项目,并可以访问对象等。当然,这不是应该的,也不是必须的。
如果我得到解决,我会感到惊讶。
答案 0 :(得分:4)
这是人们在使用NHibernate时遇到的常见问题。这是因为:
你有几个选择:
在您的情况下,由于Spring正在为您管理您的交易,第二个选项可能是最快/最简单的解决方案。
var creditrules = Session.CreateCriteria(typeof(OrderCredit));
creditrules.Add(Restrictions.Eq("Id", ordercreditid))
.SetFetchMode("OrderObject", FetchMode.Eager);
这会在您加载OrderObject
时加载OrderCredit
。