早上好,
我对NHibernate非常陌生。我想在我的新项目中使用它,但是我遇到了一个外键引用的问题。我不知道为什么会发生这个问题。
显示的错误消息是:not-null property references a null or transient value Tec.Core.Model.Budget.oInvestmentType
下面是我的表模式:

这是我的映射文件
机场
Airport.hbm.xml
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2">
<class name="Tec.Core.Model.Airport, Tec.Core" table="tblAirport" lazy="false">
<id name="ID" column="AirportID" unsaved-value="0">
<generator class="identity" />
</id>
<property name="AirportCode" column="AirportCode" />
<property name="AirportFullName" column="AirportFullName" />
<bag name="Budgets" table="tblBudget" inverse="true" cascade="save-update">
<key column="AirportID" />
<one-to-many class="Tec.Core.Model.Budget, Tec.Core" />
</bag>
</class>
</hibernate-mapping>Airports.cs
public class Airport:Entity<int>
{
private string _airportCode="";
private string _airportFullName="";
private IList<Budget> _airportBudgets = new List<Budget>();
private Airport() { }
public Airport(string AirportCode, string AirportFullName) {
this._airportCode = AirportCode;
this._airportFullName = AirportFullName;
}
public string AirportCode {
get { return _airportCode; }
set { _airportCode = value; }
}
public string AirportFullName {
get { return _airportFullName; }
set { _airportFullName = value; }
}
public IList<Budget> Budgets {
get { return new List<Budget>(_airportBudgets).AsReadOnly(); }
protected set { _airportBudgets = value; }
}
public void AddBudget(Budget air_budget){
if (air_budget != null && !_airportBudgets.Contains(air_budget)){
air_budget.oAirport = this;
_airportBudgets.Add(air_budget);
}
}
public override int GetHashCode(){
return (GetType().FullName + "|" + _airportCode.GetHashCode()).GetHashCode();
}
}InvestmentCode
InvestmentCode.hbm.xml
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2">
<class name="Tec.Core.Model.InvestmentCode, Tec.Core" table="tblInvestmentCode" lazy="false">
<id name="ID" column="InvestmentCodeID" unsaved-value="0">
<generator class="identity" />
</id>
<property name="InvCode" column="InvestmentCode" />
<property name="InvCodeNote" column="InvestmentCodeNote" />
<bag name="Budgets" table="tblBudget" inverse="true" cascade="save-update">
<key column="InvestmentCodeID" />
<one-to-many class="Tec.Core.Model.Budget, Tec.Core" />
</bag>
</class>
</hibernate-mapping>InvestmentCode.cs
公共类InvestmentCode:实体{ 私有字符串_investmentCode=“;私有字符串_investmentCodeNote=”;私有IList _lstinvestmentCodeBudgets =新列表();私有InvestmentCode() {} public InvestmentCode(string investmentCode,string InvestmentCodeNote) { this._investmentCode = investmentCode;}公共字符串InvCodeNote { get {返回_investmentCodeNote;} set { _investmentCodeNote = value;}}公共IList预算{ get {返回新列表( _lstinvestmentCodeBudgets ).AsReadOnly();}受保护的集合{_lstinvestmentCodeBudgets=值;}公开无效!_lstinvestmentCodeBudgets.Contains(investment_code_budget)){ AddBudget(预算investment_code_budget) { if (investment_code_budget != null &investment_code_budget investment_code_budget.oInvestmentCode = this;_lstinvestmentCodeBudgets.Add(investment_code_budget);)}}公共覆盖int GetHashCode(){ GetType().FullName+“AC.26”+_investmentCode.GetHashCode().GetHashCode();}
InvestmentType
InvestmentType.hbm.xml
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2">
<class name="Tec.Core.Model.InvestmentType, Tec.Core" table="tblInvestmentType" lazy="false">
<id name="ID" column="InvestmentTypeID" unsaved-value="0">
<generator class="identity" />
</id>
<property name="InvestmentTypeNote" column="InvestmentTypeNote" />
<bag name="Budgets" table="tblBudget" inverse="true" cascade="save-update">
<key column="InvestmentTypeID" />
<one-to-many class="Tec.Core.Model.Budget, Tec.Core" />
</bag>
</class>
</hibernate-mapping>InvestmentType.cs
公共类InvestmentType:实体{ 私有字符串_investmentTypeNote=“;私有IList _lstInvestmentTypeBudgets =新列表();私有InvestmentType() {} public InvestmentType(string InvestmentTypeNote){ this._investmentTypeNote = InvestmentTypeNote;}公共字符串InvestmentTypeNote { get {返回_investmentTypeNote;} set { _investmentTypeNote = value;} public IList预算{ get {返回新列表(_lstInvestmentTypeBudgets).AsReadOnly();}受保护的集合{ _lstInvestmentTypeBudgets =值;}公共无效AddBudget(预算investment_type_budget) { if (investment_type_budget != null && _lstInvestmentTypeBudgets investment_type_budget.oInvestmentType = this;_lstInvestmentTypeBudgets.Add(investment_type_budget);)}}公共覆盖int GetHashCode(){ GetHashCode (GetType().FullName +“AC.26”+GetType})}
预算
Budget.hbm.xml
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2">
<class name="Tec.Core.Model.Budget, Tec.Core" table="tblBudget" lazy="false">
<id name="ID" column="BudgetID" unsaved-value="0">
<generator class="identity" />
</id>
<property name="BudgetAmount" column="BudgetAmount" />
<property name="BudgetYear" column="BudgetYear" />
<many-to-one name="oAirport" column="AirportID"
class="Tec.Core.Model.Airport, Tec.Core" not-null="true" />
<many-to-one name="oInvestmentCode" column="InvestmentCodeID"
class="Tec.Core.Model.InvestmentCode, Tec.Core" not-null="true" />
<many-to-one name="oInvestmentType" column="InvestmentTypeID"
class="Tec.Core.Model.InvestmentType, Tec.Core" not-null="true" />
</class>
</hibernate-mapping>Budget.cs
public class Budget:Entity<long> { private float \_budgetAmount; private int \_budgetYear; private InvestmentType \_investmentType; private InvestmentCode \_investmentCode; private Airport \_airport; public Budget() { } public float BudgetAmount { get{return \_budgetAmount; } set{\_budgetAmount = value;} } public int BudgetYear { get{return \_budgetYear; } set{\_budgetYear = value;} } public Airport oAirport{ get{return \_airport; } set{\_airport = value;} } public InvestmentType oInvestmentType{ get{return \_investmentType; } set{\_investmentType = value;} } public InvestmentCode oInvestmentCode { get{return \_investmentCode ; } set{\_investmentCode = value;} } public override int GetHashCode(){ return (GetType().FullName + "|" + \_airport.GetHashCode() +"|"+ \_investmentCode.GetHashCode()+"|"+ \_investmentType.GetHashCode()).GetHashCode(); } }
在我的Default.asp.cs里
我有以下代码:
Airport objA = new Airport("NA", "New Airport")
InvestmentCode objIC = new InvestmentCode("1000", "ABCD");
InvestmentType objIT = new InvestmentType("Capex");
Budget objBg = new Budget();
objBg.oAirport = objA;
objBg.oInvestmentCode = objIC;
objBg.oInvestmentType = objIT;
objBg.BudgetAmount = 10000;
objBg.BudgetYear = 2014;
objA.AddBudget(objBg);
AirportDao.SaveOrUpdate(objA);
objIC.AddBudget(objBg);
daoFactory.GetInvestmentCodeDao().Save(objIC); //Error occur here not-null property references a null or transient value Tec.Core.Model.Budget.oInvestmentType
objIT.AddBudget(objBg);
daoFactory.GetInvestmentTypeDao().Save(objIT); 发布于 2014-02-25 02:44:40
我不会把我的生命押在上面..。但我要说你的问题是:
public IList<Budget> Budgets {
get { return new List<Budget>(_lstinvestmentCodeBudgets).AsReadOnly(); }
protected set { _lstinvestmentCodeBudgets = value; }
}此代码按以下顺序调用:
objA.AddBudget(objBg);
AirportDao.SaveOrUpdate(objA);objA被持久化。objBg也是级联和持久化的。这意味着NHiberante会跟踪对NHiberante的引用。
那你就把这叫做:
objIC.AddBudget(objBg);按预期将预算添加到列表中。我们把这份名单叫做“名单A”。
然后你去打电话给保存:
daoFactory.GetInvestmentCodeDao().Save(objIC);当NHibernate开始从您的实体读取值时。这是你的灵感来源:
get { return new List<Budget>(_lstInvestmentTypeBudgets).AsReadOnly(); }你已经把你的财产包装在一个新的列表中了。所以现在,这是“名单B”。不是NHibernate所期望的“列表A”。“名单B”没有被坚持。所以NHibernate说:“等等.你想坚持我在更新中没有跟踪的东西”。
尝试将您的getter更改为:
get { return _lstInvestmentTypeBudgets; }..and看看这是否有效。应该..。因为你要返回相同的实例。
发布于 2014-02-25 03:03:09
地图需要稍加修正。预算是一个与机场、投资和InvestmentCode有关的实体。预算不能像子类一样添加到这里的其他类中,因为这里没有任何人与许多类的关系。因此,请从这三个类中删除addBudget方法,并将以下方法添加到Budget类-> AddAirport, AddInvestmentCode, AddInvestmentType中。Update:通过从机场、投资类型和代码中移除指向预算类的袋子,从而相应地更正映射
https://stackoverflow.com/questions/22003511
复制相似问题