gpt4 book ai didi

nhibernate - 在这种情况下,为什么 NHibernate 在 ISession.Refresh 期间抛出 "GenericADOException : could not initialize a collection"异常?

转载 作者:行者123 更新时间:2023-12-04 12:56:06 26 4
gpt4 key购买 nike

我一直在使用 ISession.Refresh() 遇到奇怪的行为(至少对我而言) .

我有一个带有延迟加载的子项集合的实体,以及一个命中该集合的只读属性,所有这些都包含在二级缓存中。
我用 ISession.Refresh()在向DB提交事务后,在长时间的 session 中获取最新数据,并得到以下错误:

NHibernate.Exceptions.GenericADOException : could not initialize a collection: [Test.NUnit.DBTest.TestModel.ParentTestEntity.Children#d4251363-cf88-4684-b65a-9f330107afcf][SQL: SELECT children0_.ParentTestEntity_id as ParentTe4_1_, children0_.Id as Id1_, children0_.Id as Id42_0_, children0_.RowVersion as RowVersion42_0_, children0_.Parent_id as Parent3_42_0_ FROM "ChildTestEntity" children0_ WHERE children0_.ParentTestEntity_id=?]
----> System.NullReferenceException : Object reference not set to an instance of an object.
at NHibernate.Loader.Loader.LoadCollection(ISessionImplementor session, Object id, IType type)
at NHibernate.Loader.Collection.CollectionLoader.Initialize(Object id, ISessionImplementor session)
at NHibernate.Persister.Collection.AbstractCollectionPersister.Initialize(Object key, ISessionImplementor session)
at NHibernate.Event.Default.DefaultInitializeCollectionEventListener.OnInitializeCollection(InitializeCollectionEvent event)
at NHibernate.Impl.SessionImpl.InitializeCollection(IPersistentCollection collection, Boolean writing)
at NHibernate.Collection.AbstractPersistentCollection.Initialize(Boolean writing)
at NHibernate.Collection.AbstractPersistentCollection.ReadSize()
at NHibernate.Collection.PersistentBag.get_Count()
DBTest\TestModel\EntiteTestCacheCollectionsParent.cs(25,0): at Test.NUnit.DBTest.TestModel.ParentTestEntity.get_Count()
at (Object , GetterCallback )
at NHibernate.Bytecode.Lightweight.AccessOptimizer.GetPropertyValues(Object target)
at NHibernate.Tuple.Entity.PocoEntityTuplizer.GetPropertyValuesWithOptimizer(Object entity)
at NHibernate.Tuple.Entity.PocoEntityTuplizer.GetPropertyValues(Object entity)
at NHibernate.Persister.Entity.AbstractEntityPersister.GetPropertyValues(Object obj, EntityMode entityMode)
at NHibernate.Event.Default.AbstractVisitor.Process(Object obj, IEntityPersister persister)
at NHibernate.Event.Default.DefaultRefreshEventListener.OnRefresh(RefreshEvent event, IDictionary refreshedAlready)
at NHibernate.Event.Default.DefaultRefreshEventListener.OnRefresh(RefreshEvent event)
at NHibernate.Impl.SessionImpl.FireRefresh(RefreshEvent refreshEvent)
at NHibernate.Impl.SessionImpl.Refresh(Object obj)
DBTest\NHibernateBehaviorTests.cs(610,0): at Test.NUnit.DBTest.NHibernateBehaviorTests.Test()
--NullReferenceException
at NHibernate.Engine.Loading.CollectionLoadContext.AddCollectionToCache(LoadingCollectionEntry lce, ICollectionPersister persister)
at NHibernate.Engine.Loading.CollectionLoadContext.EndLoadingCollection(LoadingCollectionEntry lce, ICollectionPersister persister)
at NHibernate.Engine.Loading.CollectionLoadContext.EndLoadingCollections(ICollectionPersister persister, IList`1 matchedCollectionEntries)
at NHibernate.Engine.Loading.CollectionLoadContext.EndLoadingCollections(ICollectionPersister persister)
at NHibernate.Loader.Loader.EndCollectionLoad(Object resultSetId, ISessionImplementor session, ICollectionPersister collectionPersister)
at NHibernate.Loader.Loader.InitializeEntitiesAndCollections(IList hydratedObjects, Object resultSetId, ISessionImplementor session, Boolean readOnly)
at NHibernate.Loader.Loader.DoQuery(ISessionImplementor session, QueryParameters queryParameters, Boolean returnProxies)
at NHibernate.Loader.Loader.DoQueryAndInitializeNonLazyCollections(ISessionImplementor session, QueryParameters queryParameters, Boolean returnProxies)
at NHibernate.Loader.Loader.LoadCollection(ISessionImplementor session, Object id, IType type)

这是一个单元测试,显示了简化模型的问题:
    [Test]
public void Test()
{
ISession session1 = NHibernateHelper.SessionFactory.OpenSession();
ISession session2 = NHibernateHelper.SessionFactory.OpenSession();

// Create a new entity tree and persist it
ParentTestEntity parentSession1 = new ParentTestEntity();
parentSession1.AddChild(new ChildTestEntity());
session1.Save(parentSession1);
session1.Flush();

// Load the saved object into another session
ParentTestEntity parentSession2 = session2.Get<ParentTestEntity>(parentSession1.Id);
session2.Refresh(parentSession2); // Throws here
}

以下是涉及的实体:
public class ParentTestEntity
{
public virtual Guid Id { get; private set; }
public virtual long RowVersion { get; private set; }

public virtual IList<ChildTestEntity> Children { get; protected set; }

public ParentTestEntity()
{
this.Children = new List<ChildTestEntity>();
}

public virtual int Count
{
get
{
return Children.Count;
}

set { }
}

public virtual void AddChild(ChildTestEntity child)
{
if (this.Children == null)
{
this.Children = new List<ChildTestEntity>();
}

this.Children.Add(child);
child.Parent = this;
}
}

public class ChildTestEntity
{
public virtual Guid Id { get; private set; }
public virtual long RowVersion { get; private set; }

public virtual ParentTestEntity Parent { get; set; }
}

以及它们的映射:
public class ParentTestEntityMap : ClassMap<ParentTestEntity>
{
public ParentTestEntityMap()
{
Cache.ReadWrite();

Id(x => x.Id)
.GeneratedBy.GuidComb();

Version(x => x.RowVersion);

HasMany(x => x.Children)
.Inverse()
.Cascade.All()
.Cache.ReadWrite();

Map(x => x.Count);
}
}

public class ChildTestEntityMap : ClassMap<ChildTestEntity>
{
public ChildTestEntityMap()
{
Cache.ReadWrite();

Id(x => x.Id)
.GeneratedBy.GuidComb();

Version(x => x.RowVersion);

References(x => x.Parent)
.Not.Nullable();
}
}

在我的测试中,我发现:
  • 删除 Count 的映射属性(property),
  • 删除 Cache.ReadWrite()映射,
  • 枚举之前的集合 Refresh ,

  • 足够 Refresh正常工作。

    任何人都知道我可以做些什么来让刷新工作?

    笔记:
  • 我可以在 NHibernate 2.1.2 和 3.1.0 中重现这种行为,
  • 我知道 Count 中的空二传手难看,这里只是为了反射(reflect)实体在真实模型中的映射。
  • 最佳答案

    使用 Load()代替 Get()解决了这个问题。

    这不是通用的解决方案,如 Load()语义略有不同,如果相应的行不存在,则会抛出。

    不过,这是我们架构中可接受的约束,因为我们知道加载的实体存在于数据库中。

    任何解决方案 Get()不过还是很受欢迎的。

    关于nhibernate - 在这种情况下,为什么 NHibernate 在 ISession.Refresh 期间抛出 "GenericADOException : could not initialize a collection"异常?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6913995/

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