在NHibernate中合并分离的对象图

时间:2017-07-06 19:43:37

标签: c# nhibernate lazy-loading castle-activerecord

我正在努力解决我在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的集合。

干杯,

尼尔

1 个答案:

答案 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将会失败。