我正在努力解决我在Hibernate中从未遇到的NHibernate问题。我有一个带有延迟加载集合的对象。我在一个会话中加载对象,然后我想在另一个会话中重新连接它并初始化延迟加载的集合。但是,我一直认为收集与会话无关。错误。要合并的代码非常简单:
/// <summary>
/// Loads all the lazy collections in the sample types
/// </summary>
/// <param name="sampleTypes"></param>
public static void FullyLoadSampleTypes(ICollection<SampleType> sampleTypes)
{
using (SessionScopeWrapper ssw = new SessionScopeWrapper(FlushAction.Never))
{
sampleTypes.ForEach(st =>
{
if (!NHibernateUtil.IsInitialized(st.MasterKeyValuePairs))
{
ssw.Session.Merge(st);
NHibernateUtil.Initialize(st.MasterKeyValuePairs);
}
});
}
}
合并执行但初始化调用会抛出与会话错误无关的&#39; - 请注意我在Hibernate 3上(目前由于依赖Activerecord而被锁定)。我原以为Merge会重新关联sampleType对象和它的集合吗?
有人可以为我说清楚情况吗?请注意,我可以在一个会话中加载整个事物(包括惰性集合),但我需要知道如何重新附加和延迟加载NHibernate的集合。
干杯,
尼尔
答案 0 :(得分:1)
Merge
用于将分离的实体对象复制到第二个会话中对应的其他对象。然后,Merge
返回第二个会话中的相应对象。
之后你的分离对象仍然分离。
如果您这样做,您的代码不会崩溃:
if (!NHibernateUtil.IsInitialized(st.MasterKeyValuePairs))
{
var merged = ssw.Session.Merge(st);
NHibernateUtil.Initialize(merged.MasterKeyValuePairs);
}
这在Merge
xml评论(强调我的)中有记载。
将给定对象的状态复制到具有相同标识符的持久对象上。如果当前没有与会话关联的持久性实例,则将加载该实例。返回持久化实例。如果给定实例未保存,请保存副本并将其作为新的持久实例返回。 给定的实例不会与会话相关联。
也许这不适合你。如果您希望将分离的对象与第二个会话相关联,则需要在第二个会话中Update
它。当然,Update
xml注释并未明确说明。但要注意(来自<remarks>
):
如果存在具有相同标识符的持久化实例,则抛出异常。
这意味着如果您的第二个会话已经加载了同一个实体,Update
将会失败。