我从一个MVC3应用程序调用的WCF项目开始使用NHibernate。 一切似乎都没问题,但为了优化数据库上的请求我想使用FecthMode.Eager,但是在集合上我收到了这个错误:
未能懒惰地初始化集合,没有会话或会话关闭
以下是我的WCF服务的代码(简化):
映射:
Statement.hbm.xml
<?xml version="1.0" encoding="utf-8"?>
<hibernate-mapping assembly="MyWCFNameSpace.Domain" namespace="MyWCFNameSpace.Contract" xmlns="urn:nhibernate-mapping-2.2">
<class name="StatementInfo" table="STATEMENT" lazy="false" >
<id name="NumStatement" column="NUM_STATEMENT">
<generator class="identity" />
</id>
<property name="TypeStatement">
<column name="TYPE_STATEMENT" sql-type="VARCHAR2" not-null="false" />
</property>
<one-to-one name="AddressStatement" class="AddressStatementInfo" cascade="all" />
<bag name="NHBlocList" inverse="true" cascade="all">
<key>
<column name="NUM_STATEMENT" />
</key>
<one-to-many class="BlocInfo" />
</bag>
</class>
</hibernate-mapping>
Address.hbm.xml
<?xml version="1.0" encoding="utf-8"?>
<hibernate-mapping assembly="MyWCFNameSpace.Domain" namespace="MyWCFNameSpace.Contract" xmlns="urn:nhibernate-mapping-2.2">
<class name="AddressInfo" table="ADDRESS" lazy="false" >
<id name="NumStatement" column="NUM_STATEMENT">
<generator class="identity" />
</id>
<property name="LineAdresse1">
<column name="LINE_ADDRESS_1" sql-type="VARCHAR2" not-null="false" />
</property>
<property name="LineAdresse2">
<column name="LINE_ADDRESS_2" sql-type="VARCHAR2" not-null="false" />
</property>
<property name="Country">
<column name="COUNTRY" sql-type="VARCHAR2" not-null="false" />
</property>
</class>
</hibernate-mapping>
Bloc.hbm.xml
<?xml version="1.0" encoding="utf-8"?>
<hibernate-mapping assembly="MyWCFNameSpace.Domain" namespace="MyWCFNameSpace.Contract" xmlns="urn:nhibernate-mapping-2.2">
<class name="BlocInfo" table="BLOC" lazy="false" >
<composite-id>
<key-property name="NumStatement" column="NUM_STATEMENT" />
<key-property name="NumBloc" column="NUM_BLOC" />
</composite-id>
<property name="BlocType">
<column name="BLOC_TYPE" sql-type="VARCHAR2" not-null="false" />
</property>
</class>
</hibernate-mapping>
DAO代码:
StatementDao.cs
[Repository]
public class StatmentDao : HibernateDao, IStatmentDao
{
public StatmentDao() { }
//...
[Transaction]
public StatmentInfo GetStatment(string numStatment)
{
return (StatmentInfo)CurrentSession.CreateCriteria<StatmentInfo>()
.SetFetchMode("Address", global::NHibernate.FetchMode.Eager)
.SetFetchMode("NHBlocList", global::NHibernate.FetchMode.Eager)
.Add(Restrictions.Eq("NumStatment", numStatment))
.UniqueResult();
}
服务类:
public class MyWCFServiceImpl : MyWCFService
{
public IStatementDao StatementDao { get; set; }
public override GetStatementResponse GetStatement(GetStatementRequest request)
{
if (request == null || string.IsNullOrEmpty(request.NumStatement))
return null;
GetStatementResponse response = new GetStatementResponse();
response.Statement = StatementDao.GetStatement(request.NumStatement);
return response;
}
和测试课
[TestFixture]
public class GetStatementTest : AbstractIntegrationTests
{
private IApplicationContext ctx;
public IMyWCFService MyWCFService { get; set; }
[SetUp]
public void InitContext()
{
// Configure Spring programmatically
ctx = ContextRegistry.GetContext();
}
[Test]
public void GetStatement()
{
MyWCFService = (IMyWCFService)ctx.GetObject("myWCFService");
GetStatementResponse response;
response = EmissaireGUService.GetStatement(
new GetStatementRequest()
{
NumStatement = "STATEMENT_1",
});
// Asserts...
}
如果没有FetchMode.Eager,nhibernate会生成3个请求:
SELECT ... FROM STATEMENT this_ WHERE this_.NUM_STATEMENT = :p0
SELECT ... FROM ADDRESS address10_ WHERE address10.NUM_STATEMENT = :p0
SELECT ... FROM BLOC nhbloclist0_ WHERE bloclist0_.NUM_RELEVE=:p0
这对表演来说并不好(我的真实代码是最复杂的,我得到了20个请求)。这就是我尝试使用FetchMode.Eager只生成一个请求的原因。
在地址上使用FetchMode.Eager我现在只有2个请求:
SELECT ... FROM STATEMENT this_ left outer join ADDRESS address10_ on this_.NUM_STATEMENT =address10_.NUM_STATEMENT WHERE this_.NUM_STATEMENT = :p0
SELECT ... FROM BLOC nhbloclist0_ WHERE bloclist0_.NUM_RELEVE=:p0
对我来说这是一个好的开始,但是当我尝试在blocs集合上做同样的事情时,我得到了懒惰的初始化异常。
我试图在任何地方设置lazy = false,但我没有得到任何结果。 在问我在互联网上进行了一些挖掘之前,但我没有找到太多(在我的理解水平上),除非可能是会议的问题太早关闭,但我不知道如何解决这个问题。
至少先谢谢你指出正确的方向。