我有一个插入StatelessSession
的实体(手工构建)。它有一个深藏的收藏品结构。我想在普通Session
中使用此对象,以便跟踪并使用Commit
保存更改。我需要欺骗NHibernate认为它自己创建了这个实体。这应该在没有实际访问数据库的情况下完成。
以下是NH源链接:https://github.com/nhibernate/nhibernate-core/
我整天调试了它,但仍然没有解决方案。问题是所有集合都应该包含IPersistentCollection
。我实现了这一点,但封装器仍未以正确的方式初始化。
var m = s.FlushMode;
s.FlushMode = FlushMode.Never; // do not update anything until I say
try
{
s.Lock(DbEntity, LockMode.None); // throws "reassociated object has dirty collection reference"
}
catch
{
s.Lock(DbEntity, LockMode.None); // second works but then updates db on flush!
var sessionImpl = s as SessionImpl;
var state = sessionImpl.PersistenceContext.GetEntry(DbEntity);
IEntityPersister persister = sessionImpl.Factory.GetEntityPersister(state.EntityName);
WrapVisitor visitor = new WrapVisitor(sessionImpl);
// substitutes into values by side-effect
object[] propertyValues = persister.GetPropertyValues(DbEntity, sessionImpl.EntityMode);
visitor.ProcessEntityPropertyValues(propertyValues, persister.PropertyTypes);
persister.SetPropertyValues(DbEntity, propertyValues, sessionImpl.EntityMode);
var lockMode = state.LockMode;
state.PostUpdate(DbEntity, propertyValues, state.Version);
state.LockMode = lockMode;
var types = persister.PropertyTypes;
// should initialize wrappers Role, Key and Snapshot
// will this handle nested collections? I don't know...
for (int i = 0; i < propertyValues.Length; i++)
{
var collection = propertyValues[i] as IPersistentCollection;
if (collection == null) continue;
var collectionType = (CollectionType)types[i];
ICollectionPersister collectionPersister = sessionImpl.Factory.GetCollectionPersister(collectionType.Role);
// nope, this doesn't work :((
sessionImpl.PersistenceContext.AddInitializedCollection(collectionPersister, collection, null);
//sessionImpl.PersistenceContext.AddInitializedDetachedCollection(collectionPersister, collection);
}
// now collections should be initialized as they were attached to session
s.Clear(); // second attempt should now work
s.Lock(DbEntity, LockMode.None); // exception, IPersistentCollection doesn't have a key and role!!!
s.FlushMode = m; // updates on
// work with DbEntity here
curTr.Commit();
}
我知道我不应该做这件事。但是,当我需要更新一个小房产时,我不喜欢NH读取数据库的方式。我没有使用二级缓存,因为我使用有状态服务包装我的实体并手动缓存它们。我不希望将相同的数据缓存两次。
那怎么办呢?