我有一些对象,其中一些具有文档列表,其他对象,......等等。我不想lazy=false
在关系上使用,因为它使应用程序非常慢。我可以使用 Lock 重新附加对象,以便在需要时加载其他属性或一对多关系。但是对于集合,如果我尝试访问它们,我总是会得到“无法初始化集合”。Lock(obj)
如果我调用连接到该位置的对象,它将不起作用。
我希望我的映射看起来像这样:
<set name="DocumentList" table="material_document" cascade="all" lazy="true">
<key column="material_id"/>
<many-to-many class="Document">
<column name="document_id"/>
</many-to-many>
</set>
有没有办法重新连接?还是有映射设置?
更新1:
这是物质方面的映射:
<?xml version="1.0" encoding="utf-8"?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
<class name="Material" table="material">
<!-- Defining PK -->
<id name="Id" type="integer" column="id">
<generator class="sequence">
<param name="sequence">material_id_seq</param>
</generator>
</id>
<!-- Defining Properties -->
<!-- Defining FK-Relations -->
<set name="DocumentList" table="material_document" cascade="all" lazy="false">
<key column="material_id"/>
<many-to-many class="Document">
<column name="document_id"/>
</many-to-many>
</set>
文档映射文件没有关于关系的任何信息。数据库名称没问题,其他一切正常。这些表称为material
和。我的课程是和属性。我的实体有什么问题?您的意思是数据有问题还是程序中的对象可能发生了某些事情......?material_document
document
public
public virtual
List material = LoadAllMaterials();
//some code, that causes the session to be closed, a new session will be opened
foreach (Document d in material.DocumentList) { //causes the exception
//do something
}
在此之前,我想获取文档,而不是事先加载它们。
更新 2: 我目前如何重新附加对象:当我知道有代理并且它不能以另一种方式工作时,我将 force true 设置为……而且我必须检查它是否在会话中,因为如果我调用它,evict 会抛出一个异常在不在会话中的对象上。
public void Reattach(Type type, BaseObject o, bool force)
{
bool inSession = o.IsInSession();
if (force && inSession)
{
GetSession().Evict(o);
GetSession().Lock(type.ToString(), o, LockMode.None);
}
else {
o = (BaseObject)GetSession().GetSessionImplementation().PersistenceContext.Unproxy(o);
if (!inSession) {
GetSession().Lock(type.ToString(), o, LockMode.None);
}
}
}
这是我的 IsInSession() 方法:
public virtual bool IsInSession() {
ISession session = HibernateSessionManager.Instance.GetSession();
var pers = session.GetSessionImplementation()
.GetEntityPersister(GetType().ToString(), this);
NHibernate.Engine.EntityKey key = new NHibernate.Engine.EntityKey(Id,
pers, EntityMode.Poco);
bool isInSession = false;
try
{
object entity = session.GetSessionImplementation().PersistenceContext.GetEntity(key);
if (entity != null)
{
isInSession = true;
}
}
catch (NonUniqueObjectException) {}
return isInSession;
}