我已经阅读了很多问题和答案,但我找不到解决问题的方法。当我从NHibernate 1.2.1迁移到2.1.2时会出现问题。 我有这个常见的错误:
对象引用未保存的瞬态实例 - 在刷新之前保存瞬态实例。键入:Mikro.FareOn.Modules.Cards.Interface.BEC.CRResidenceRegion,实体:Mikro.FareOn.Modules.Cards.Interface.BEC.CRResidenceRegion
NHibernate configuration: <nhibernate> <add key="hibernate.show_sql" value="true" /> <add key="hibernate.connection.provider" value="NHibernate.Connection.DriverConnectionProvider" /> <add key="dialect" value="NHibernate.Dialect.MsSql2005Dialect" /> <add key="proxyfactory.factory_class" value="NHibernate.ByteCode.Castle.ProxyFactoryFactory, NHibernate.ByteCode.Castle" /> <add key="driver_class" value="NHibernate.Driver.SqlClientDriver" /> <add key="connection.connection_string" value="..." /> </nhibernate>
主类CRResidence的映射:
<?xml version="1.0" encoding="utf-8" ?> <hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" default-lazy="false"> <class name="Mikro.FareOn.Modules.Cards.Interface.BEC.CRResidence, Mikro.FareOn.Modules.Cards.Interface" table="CR_Residence"> <id name="Id" column="id" type="Int64" access="nosetter.camelcase" unsaved-value="0"> <generator class="identity" /> </id> <version name="VersionId" column="version_id" type="Int64" /> <property name="IsDeleted" column="deleted" type ="Boolean" not-null="true" /> <property name="Name" column="name" type="String" not-null="true" /> <many-to-one name="Region" column="region_id" cascade="none" class="Mikro.FareOn.Modules.Cards.Interface.BEC.CRResidenceRegion, Mikro.FareOn.Modules.Cards.Interface"/> <property name="Postcode" column="postcode" type="String" not-null="true" /> <many-to-one name="Country" column="residence_country_id" cascade="none" class="Mikro.FareOn.TransportOperator.Interface.BEC.TOResidenceCountry, Mikro.FareOn.TransportOperator.Interface"/> </class> </hibernate-mapping>
与多对一关系的课程之一:
<?xml version="1.0" encoding="utf-8" ?> <hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" default-lazy="false"> <class name="Mikro.FareOn.Modules.Cards.Interface.BEC.CRResidenceRegion, Mikro.FareOn.Modules.Cards.Interface" table="CR_ResidenceRegion" > <id name="Id" column="id" type="Int64" access="nosetter.camelcase" unsaved-value="0"> <generator class="identity" /> </id> <version name="VersionId" column="version_id" type="Int64" /> <property name="Name" column="name" type="String" not-null="true" /> <property name="IsDeleted" column="deleted" type ="Boolean" not-null="true" /> </class> </hibernate-mapping>
CRResidenceRegion类的实现:
[Serializable] public class CRResidence : BussinesEntityComponentBase //this is class, which implements Equals and define Id, VersionId, IsDeleted { string name; string postcode; CRResidenceRegion region; TOResidenceCountry country; #region Getters/Setters /// /// Nazev mista /// public string Name { get { return this.name; } set { this.name = value; } } /// /// Region /// public CRResidenceRegion Region { get { return this.region; } set { this.region = value; } } /// /// Stát /// public TOResidenceCountry Country { get { return this.country; } set { this.country = value; } } /// /// PSC /// public string Postcode { get { return this.postcode; } set { this.postcode = value; } } public string PostcodeAndName { get { return String.Format("{0} - {1}", Postcode, Name); } } public string NameAndPostcode { get { return String.Format("{1} - {0}", Postcode, Name); } } #endregion /// /// Konstruktor objektu rezidence /// public CRResidence() : base() { } }
我尝试了所有类型的级联,但任何级联都无法正常工作。但在我的场合,我更喜欢cascade =“none”。 我有客户端,在一个NHibernate会话中通过调用服务器端的方法加载对象CRResidenceRegion。加载后,NHibernate会话关闭。客户端上的对象是正确的,来自数据库的正确ID等等。然后向CRResidence对象分配CRResidenceRegion对象。 然后在服务器端调用它的方法:
using (PersistenceSession session = Registrator.OpenSession()) { ITransaction trx = session.BeginTransaction(); try { session.Update(residence); //residence.Region = (CRResidenceRegion)session.Get(typeof(CRResidenceRegion), residence.Region.Id); //residence.Country = (TOResidenceCountry)session.Get(typeof(TOResidenceCountry), residence.Country.Id); trx.Commit(); log.Debug("CRResidence updated."); return residence; } catch (Exception ex) ............ }
我有很多像这样的对象,当我迁移到NHibernate 2.1.2时出现了这个问题。在某些情况下定义级联风格后工作正常(“无”工作以及“所有”,我需要的地方)。可能是NHibernate配置文件中的问题。
问题的先前定义: 当我尝试插入或更新CRResidence的实例时,会发生有关未保存的瞬态错误的错误。 CRResidenceRegion的实例已完全初始化,包括Id,因此没有问题。我在Id上实现了Equal方法。我试图清除缓存,但它没有帮助。当我将级联更改为保存更新时,它可以工作,但CRResidenceRegion的记录是重复的。一个解决方案是我在保存CRResidence之前在同一个会话中读取CRResidenceRegion(在下面的代码中注释),但这是不可接受的。
似乎NHibernate已经失去了对CRResidenceRegion的引用,并认为它是新创建的,但事实并非如此。
答案 0 :(得分:1)
使用Session.Load方法而不是Get来初始化CRResidenceRegion实体。除非您访问其任何属性,否则这实际上不会进入数据库。
...
residence.Region = session.Load<CRResidenceRegion>(residence.Region.Id);
session.Update(residence);
trx.Commit();
...
答案 1 :(得分:0)
这可能是因为它来自另一个激情。
请尝试session.Merge()
。
答案 2 :(得分:0)
我找到了解决问题的方法。 问题出在version_id中,我已将未保存的值添加到CR_ResidenceRegion的映射文件中。
<version name="VersionId" column="version_id" type="Int64" unsaved-value="0" />
我认为他们更改了unsaved-value的默认值。
感谢大家的帮助