Reputation: 593
I'm using Nhibernate 3.2 and fluent nhibernate, I have two tables Customer Group and Customer, and I use for lock management version control with TimeStamp Column. I have the following classes and maps for these classes:
public class Customer
{
public Customer()
{
}
public virtual int CustomerID { get; set; }
public virtual CustomerGroup customerGroup { get; set; }
public virtual int CustomerGroupID { get; set; }
public virtual string CustomerRef { get; set; }
public virtual string NameE { get; set; }
public virtual string NameA { get; set; }
public virtual byte[] TimeStamp { get; set; }
}
and his map
public class CustomerMap : ClassMap<Customer> {
public CustomerMap() {
Table("Customer");
Id(x => x.CustomerID).GeneratedBy.Identity().Column("CustomerID");
Version(x =>x.TimeStamp).CustomType("BinaryBlob").Generated.Always().Column("TimeStamp");
DynamicUpdate();
OptimisticLock.Version();
References(x =>x.customerGroup).Column("CustomerGroupID").ForeignKey("CustomerGroupID");
Map(x => x.CustomerRef).Column("CustomerRef").Length(30).Unique();
Map(x => x.NameE).Column("NameE").Not.Nullable().Length(100).Unique();
Map(x => x.NameA).Column("NameA").Length(100);
and for Customer Group:
public class CustomerGroup {
public CustomerGroup() {
Customers = new List<Customer>(3);
}
public virtual int CustomerGroupID { get; set; }
public virtual IList<Customer> Customers { get; set; }
public virtual byte[] TimeStamp { get; set; }
}
and his map:
public CustomerGroupMap() {
Table("CustomerGroup");
Version(x => x.TimeStamp).CustomType("BinaryBlob").Generated.Always().Column("TimeStamp");
DynamicUpdate();
OptimisticLock.Version();
Id(x => x.CustomerGroupID).GeneratedBy.Identity().Column("CustomerGroupID");
HasMany(x => x.Customers).KeyColumn("CustomerGroupID");
}
When I create update in list of customers belong to specific Customer Group like this:
ISession Session = OpenSession();
Session.BeginTransaction();
var customerGroupInfo = Session.Query<CustomerGroup>().Fetch(x => x.Customers).Single<CustomerGroup>(x => x.CustomerGroupID == 98);
foreach (var item in customerGroupInfo.Customers)
{
item.NameE = "abc";
Session.Update(item);
}
Session.Transaction.Commit();
apply these sql statements:
UPDATE Customer SET NameE = 'abc'
WHERE CustomerID = 200 AND TimeStamp = 0x00000000000092EF
SELECT customer_.TimeStamp as TimeStamp1_ FROM Customer customer_
WHERE customer_.CustomerID = 200
UPDATE Customer SET NameE = 'abc'
WHERE CustomerID = 201 AND TimeStamp = 0x00000000000092F0
SELECT customer_.TimeStamp as TimeStamp1_ FROM Customer customer_
WHERE customer_.CustomerID = 201
. . .
and every update and every select operate in single round trip. I set property adonet.batch_size property in configuration like this:
<property name="adonet.batch_size">20</property>
I read in this post this behavior founded by default in Nhibernate 3.2. Any Tips to make batch work correctly?
Upvotes: 2
Views: 2077
Reputation: 2023
You might look at changing your Session.FlushMode
to something other than Automatic. That way, you could do something like this:
Session.FlushMode = NHibernate.FlushMode.Never
foreach (var item in customerGroupInfo.Customers)
{
item.NameE = "abc";
Session.Update(item);
}
Session.Flush();
Session.Transaction.Commit();
// Perhaps changing the flushmode after commit?
Session.FlushMode = NHibernate.FlushMode.Auto;
Edit :
Nevermind, see this excerpt from the docs: http://nhibernate.info/doc/nh/en/index.html#batch
It appears that batching doesn't get along with optimistic locking.
NHibernate supports batching SQL update commands (INSERT, UPDATE, DELETE) with the following limitations:
.NET Framework 2.0 or above is required,
**the Nhibernate's drive used for your RDBMS may not supports batching,**
since the implementation uses reflection to access members and types in System.Data assembly which are not normally visible, it may not function in environments where necessary permissions are not granted
**optimistic concurrency checking may be impaired since ADO.NET 2.0 does not return the number of rows affected by each statement in the batch, only the total number of rows affected by the batch.**
Upvotes: 2