2011-06-13 5 views
1

많은 질문과 답변을 읽었지만 문제에 대한 해결책을 찾지 못했습니다. 이 문제는 NHibernate 1.2.1에서 2.1.2로 마이그레이션 할 때 발생합니다. 이 일반적인 오류가 있습니다 :NHibernate 2.1.2 저장되지 않은 일시적인 인스턴스

개체는 저장되지 않은 일시적인 인스턴스를 참조합니다. - 플러시하기 전에 임시 인스턴스를 저장하십시오. 유형 : Mikro.FareOn.Modules.Cards.Interface.BEC.CRResidenceRegion, 엔티티 : Mikro.FareOn.Modules.Cards.Interface.BEC.CRResidenceRegion

 
NHibernate configuration: 
&ltnhibernate> 
      &ltadd key="hibernate.show_sql" value="true" /> 
      &ltadd key="hibernate.connection.provider" value="NHibernate.Connection.DriverConnectionProvider" /> 
      &ltadd key="dialect" value="NHibernate.Dialect.MsSql2005Dialect" /> 
      &ltadd key="proxyfactory.factory_class" value="NHibernate.ByteCode.Castle.ProxyFactoryFactory, NHibernate.ByteCode.Castle" /> 
      &ltadd key="driver_class" value="NHibernate.Driver.SqlClientDriver" /> 
      &ltadd key="connection.connection_string" value="..." />   
</nhibernate> 

메인 클래스의 CRResidence의 매핑 :

 
<?xml version="1.0" encoding="utf-8" ?> 
&lthibernate-mapping xmlns="urn:nhibernate-mapping-2.2" default-lazy="false"> 
&ltclass name="Mikro.FareOn.Modules.Cards.Interface.BEC.CRResidence, Mikro.FareOn.Modules.Cards.Interface" table="CR_Residence"> 
    &ltid name="Id" column="id" type="Int64" access="nosetter.camelcase" unsaved-value="0"> 
     &ltgenerator class="identity" /> 
    </id> 
    &ltversion name="VersionId" column="version_id" type="Int64" /> 
    &ltproperty name="IsDeleted" column="deleted" type ="Boolean" not-null="true" /> 
    &ltproperty name="Name" column="name" type="String" not-null="true" /> 
    &ltmany-to-one name="Region" column="region_id" cascade="none" class="Mikro.FareOn.Modules.Cards.Interface.BEC.CRResidenceRegion, Mikro.FareOn.Modules.Cards.Interface"/> 
    &ltproperty name="Postcode" column="postcode" type="String" not-null="true" /> 
    &ltmany-to-one name="Country" column="residence_country_id" cascade="none" class="Mikro.FareOn.TransportOperator.Interface.BEC.TOResidenceCountry, Mikro.FareOn.TransportOperator.Interface"/> 
    </class> 
</hibernate-mapping>

그리고 관계의 클래스 중 하나 다 대일 : 클래스 CRResidenceRegion의

 
<?xml version="1.0" encoding="utf-8" ?> 
&lthibernate-mapping xmlns="urn:nhibernate-mapping-2.2" default-lazy="false"> 
    &ltclass name="Mikro.FareOn.Modules.Cards.Interface.BEC.CRResidenceRegion, Mikro.FareOn.Modules.Cards.Interface" table="CR_ResidenceRegion" > 
    &ltid name="Id" column="id" type="Int64" access="nosetter.camelcase" unsaved-value="0"> 
     &ltgenerator class="identity" /> 
    </id> 
    &ltversion name="VersionId" column="version_id" type="Int64" /> 
    &ltproperty name="Name" column="name" type="String" not-null="true" /> 
    &ltproperty name="IsDeleted" column="deleted" type ="Boolean" not-null="true" /> 
    </class> 
</hibernate-mapping> 

구현 :

 
[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() 
    { 
    }  
} 

모든 유형의 캐스케이드를 시도했지만 모든 캐스케이드가 올바르게 작동하지 않습니다. 하지만 제 경우에는 계단식 = "없음"을 선호합니다. 하나의 NHibernate 세션에서 서버 쪽에서 메서드를 호출하여 CRResidenceRegion 개체를로드하는 클라이언트 쪽을 가지고 있습니다. 로드 한 후 NHibernate 세션이 닫힙니다. 클라이언트의 객체가 정확하고 데이터베이스의 올바른 ID 등등. 그런 다음 CRResidence 객체에는 CRResidenceRegion 객체가 할당됩니다. 서버 측에서 다음 그것은 호출 방법 : 내가 NHibernate에 2.1.2로 마이그레이션 할 때

 
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) 
............ 
     } 

나는이 같은 많은 개체가이 문제는 appered. 캐스케이드 스타일 ("none"뿐만 아니라 "all", 내가 필요한 곳)을 정의한 후에 어떤 경우에는 잘 작동합니다. NHibernate의 구성 파일에 문제가있을 수 있습니다.

이전 정의 문제 : CRResidence 인스턴스를 삽입하거나 업데이트하려고하면 저장되지 않은 일시적인 오류에 대한 오류가 발생합니다. ID를 포함하여 CRResidenceRegion의 인스턴스가 완전히 초기화되므로 아무런 문제가 없습니다. Id에 Equal 메서드를 구현했습니다. 캐시를 지우려고했지만 도움이되지 않았습니다. 캐스케이드를 save-update로 변경하면 작동하지만 CRResidenceRegion의 레코드는 복제됩니다. 한 가지 해결책은 CRResidence를 저장하기 전에 동일한 세션 (아래 코드에서 설명 함)에서 데이터베이스의 CRResidenceRegion을 읽는 것이지만 이는 허용되지 않습니다.

NHibernate는 적절하게 CRResidenceRegion에 대한 참조를 잃어 버렸고 새로운 것으로 생각하지만 그렇지 않습니다.

답변

0

나는 내 문제의 해결책을 발견했다. version_id에 문제가있어서 CR_ResidenceRegion의 매핑 파일에 저장하지 않은 값을 추가했습니다.

 
&ltversion name="VersionId" column="version_id" type="Int64" unsaved-value="0" /> 

기본값으로 저장되지 않은 값이 변경되었다고 생각합니다.

감사합니다.

0

이것은 다른 ession에서 온 것일 수 있습니다.

대신 session.Merge()을 시도하십시오.

+0

답장을 보내 주셔서 감사합니다.하지만 같은 오류가 다시 발생합니다. – Cvachtoun

+0

개체를 검색하고 수정하는 방법으로 질문을 업데이트 할 수 있습니까? – Meligy

+0

또한 매핑에서'cascade' 속성을 변경하려고 시도 했습니까? – Meligy

1

Get 대신 Session.Load 메서드를 사용하여 CRResidenceRegion 엔터티를 초기화합니다. 해당 속성에 액세스하지 않으면 실제로 데이터베이스로 이동하지 않습니다.

... 
residence.Region = session.Load<CRResidenceRegion>(residence.Region.Id);   
session.Update(residence); 
trx.Commit(); 
... 
+0

session.Load가 업데이트되기 전에해야하기 때문에 작동하지 않지만 어쨌든 session.Get과 같은 방식입니다. 이것은 효과가 있지만 올바른 해결책이 아닌 것 같습니다. 하지만 고마워. – Cvachtoun

+0

@user, 올바른 해결책입니다. Session.Load는 Session.Get과 완전히 다릅니다. Session.Get은 항상 데이터베이스에 반대합니다. 반면 Session.Load 필요한 경우에만 데이터베이스에 대해 이동합니다. 귀하의 경우에는 세션에서 비 일시적인 엔티티 만로드하면됩니다. Load 메서드를 사용하기 위해 db에서 가져올 필요가 없습니다. – Vadim

+0

예, 매핑 된 컬렉션을 포함하여 약 500 개의 함수를 변경해야하므로 사용할 수는 없습니다. NHibernate 1.2.1로 돌아가거나 NHibernate 사용을 중단해야합니다. 고맙습니다. – Cvachtoun

관련 문제