2011-06-03 84 views
1

我注意到在我的數據庫(SQL Server)中,我用於版本控制的列在實體添加到相關表時已更新爲實體。nhibernate 3.0樂觀鎖和相關實體

因此,舉例來說,如果我有一個Person實體,我添加了一個PersonClub,將Person的數據庫中的記錄將有一個新的版本。當然,在數據庫中,這是Club的記錄,它是使用Person的主鍵添加/更新的。

我對這種行爲感到有點驚訝,因爲Person實體沒有其他數據正在改變。

我的問題是,如果有一種方法可以關閉它;也就是說,只有當該行中的數據更改時才更新版本列。這種配置的含義是什麼?

編輯這裏是真正的代碼

型號

public partial class ObligationProgramFund : IMyObject 
{ 
    private System.Int32 _id; 
    // ... many other properties 
    private IList<ObligationProgramFundOrganization> _obligationPFOrganizations; 
    private System.Byte[] _recordVersion; 

    public ObligationProgramFund() : base() 
    { 
     _obligationPFOrganizations = new List<ObligationProgramFundOrganization>(); 
    } 

    public virtual System.Int32 Id 
    { 
     get { return _id; } 
     set { _id = value; } 
    } 

    public virtual IList<ObligationProgramFundOrganization> ObligationPFOrganizations 
    { 
     get { return _obligationPFOrganizations; } 
     set { _obligationPFOrganizations = value; } 
    } 

    public virtual System.Byte[] RecordVersion 
    { 
     get { return _recordVersion; } 
     set { _recordVersion = value; } 
    } 
} 

public partial class ObligationProgramFundOrganization : IMyObject 
{ 
    private ObligationProgramFund _obligationProgramFund; 
    private System.Int32 _id; 
    private Organization _organization; 
    private System.Byte[] _recordVersion; 
    // .. other properties 

    public ObligationProgramFundOrganization() : base() 
    { 
    } 

    public virtual System.Int32 Id 
    { 
     get { return _id; } 
     set { _id = value; } 
    } 

    public virtual System.Byte[] RecordVersion 
    { 
     get { return _recordVersion; } 
     set { _recordVersion = value; } 
    } 

    public virtual ObligationProgramFund ObligationProgramFund 
    { 
     get { return _obligationProgramFund; } 
     set { _obligationProgramFund = value; } 
    } 

    public virtual Organization Organization 
    { 
     get { return _organization; } 
     set { _organization = value; } 
    } 
} 

public partial class Organization : IMyObject 
{ 
    private IList<ObligationProgramFundOrganization> _obligationPFOrganizations; 
    private System.Int32 _id; 
    private System.Byte[] _recordVersion; 
    // other properties 

    public Organization() : base() 
    { 
     _obligationPFOrganizations = new List<ObligationProgramFundOrganization>(); 
    } 

    public virtual System.Int32 Id 
    { 
     get { return _id; } 
     set { _id = value; } 
    } 

    public virtual System.Byte[] RecordVersion 
    { 
     get { return _recordVersion; } 
     set { _recordVersion = value; } 
    } 

    public virtual IList<ObligationProgramFundOrganization> ObligationPFOrganizations 
    { 
     get { return _obligationPFOrganizations; } 
     set { _obligationPFOrganizations = value; } 
    } 
} 

映射

public partial class ObligationProgramFundMap : ClassMap<ObligationProgramFund> 
{ 
    public ObligationProgramFundMap() 
    { 
     Table("[MySchema2].[dbo].[ObligationProgramFund]"); 
     OptimisticLock.Version(); 
     DynamicUpdate(); 
     LazyLoad(); 

     Id(x=>x.Id) 
      .Access.CamelCaseField(Prefix.Underscore) 
      .Column("[Id]") 
      .GeneratedBy.Identity(); 
     Version(x=>x.RecordVersion) 
      .Access.CamelCaseField(Prefix.Underscore) 
      .Column("[RecordVersion]") 
       .CustomSqlType("timestamp") 
       .Not.Nullable() 
      .UnsavedValue("null") 
      .CustomType("BinaryBlob") 
      .Generated.Always(); 
      // other properties/components 

     HasMany(x=>x.ObligationPFOrganizations) 
      .Access.CamelCaseField(Prefix.Underscore) 
      .Cascade.AllDeleteOrphan() 
      .Fetch.Select() 
      .Inverse() 
      .LazyLoad() 
      .KeyColumns.Add("ObligationProgramFundId"); 
     } 
    } 

public partial class ObligationProgramFundOrganizationMap : ClassMap<ObligationProgramFundOrganization> 
{ 
    public ObligationProgramFundOrganizationMap() 
    { 
     Table("[MySchema2].[dbo].[ObligationProgramFundOrganization]"); 
     OptimisticLock.Version(); 
     DynamicUpdate(); 
     LazyLoad(); 

    Id(x=>x.Id) 
     .Access.CamelCaseField(Prefix.Underscore) 
     .Column("[Id]") 
     .GeneratedBy.Identity(); 
    Version(x=>x.RecordVersion) 
     .Access.CamelCaseField(Prefix.Underscore) 
     .Column("[RecordVersion]") 
      .CustomSqlType("timestamp") 
      .Not.Nullable() 
     .UnsavedValue("null") 
     .CustomType("BinaryBlob") 
     .Generated.Always(); 

    // other properties  

    References(x=>x.ObligationProgramFund) 
     .Access.CamelCaseField(Prefix.Underscore) 
     .Cascade.SaveUpdate() 
     .Fetch.Select() 
     .Columns("ObligationProgramFundId"); 
    References(x=>x.Organization) 
     .Access.CamelCaseField(Prefix.Underscore) 
     .Cascade.SaveUpdate() 
     .Fetch.Select() 
     .Columns("OrganizationId"); 
    } 
} 

public partial class OrganizationMap : ClassMap<Organization> 
{ 
    public OrganizationMap() 
    { 
     Table("[MySchema2].[dbo].[Organization]"); 
     OptimisticLock.Version(); 
     DynamicUpdate(); 
     LazyLoad(); 

     Id(x=>x.Id) 
      .Access.CamelCaseField(Prefix.Underscore) 
      .Column("[Id]") 
      .GeneratedBy.Identity(); 
     Version(x=>x.RecordVersion) 
      .Access.CamelCaseField(Prefix.Underscore) 
      .Column("[RecordVersion]") 
      .CustomSqlType("timestamp") 
      .Not.Nullable() 
      .UnsavedValue("null") 
      .CustomType("BinaryBlob") 
      .Generated.Always(); 

     // other properties 

     HasMany(x=>x.ObligationPFOrganizations) 
      .Access.CamelCaseField(Prefix.Underscore) 
      .Cascade.AllDeleteOrphan() 
      .Fetch.Select() 
      .Inverse() 
      .LazyLoad() 
      .KeyColumns.Add("OrganizationId"); 
    } 
} 

所以我的實體

Organization 1 - ∞ ObligationProgramFundOrganization ∞ - 1 ObligationProgramFund 

我觀察到的問題是,當創建新的ObligationProgramFundOrganization(關聯表)時,ObligationProgramFund的記錄版本會更新。

實際的senario是我在ObligationProgramFund編輯表單上有一個ObligationProgramFundOrganizations表。 ObligationProgramFundOrganization通過AJAX調用添加。當我去保存ObligationProgramFund時,我得到一個併發異常。我確定沒有其他用戶實際上編輯了ObligationProgramFund,因爲它都在本地運行。

+0

看起來很奇怪。俱樂部只能有一個人嗎?這將是添加一個人更新俱樂部記錄的唯一方法。你可以發佈你的類和映射嗎? – 2011-06-05 02:13:12

+0

@Diego用真實的代碼更新了我的問題。 – 2011-06-05 18:03:52

回答

0

(我已經張貼回答類似的問題:Why NHibernate UPDATE reference entity?

你必須指定版本列。這意味着任何屬性更改(甚至集合)都會觸發版本更新。

爲了防止某個屬性/集合更改版本,應該在xml映射中設置optimistic-lock =「false」屬性。