问题
I am trying to get NH batch insert to work to migrate some old data to our new DB. For a test sample I have configured batch size like so:
<property name="adonet.batch_size">25</property>
and in a stateless session I insert some 1000 objects before committing the transaction. The object id strategy is guid.comb and is mapped as follows:
<id name="Id" access="field.camelcase-underscore" type="guid" column="id">
<generator class="guid.comb"/>
</id>
Using NH Profiler I can see that all objects are inserted as individual statements and are not batched, all of them pretty much looking like:
INSERT INTO Buddies
(id)
VALUES ('81c7d3be-d718-45a4-86fe-9ef700b7ad55' /* @p0_0 */)
What might be the reason, what should I do to get batching to work?
回答1:
Try look here:
NHibernate 2.1.0.4000 doesn't seem to like batch insert
I think this is usefull too:
http://fabiomaulo.blogspot.com/2009/02/nh210-generators-behavior-explained.html
in this article, in the last example he use:
<id type="int">
<generator class="identity"/>
</id>
that seems to be the key.. have you tried?
回答2:
Insert batching only works with Session, not StatelessSession.
Stateless inserts are immediate.
回答3:
Batching of DML operations works with stateless session, but it has the same limitations than batching with state-full session, and some additional:
- It cannot batch entities inserts when those entities have post-insert retrieved ids, like
identity
generator. - It cannot batch inserts, updates or deletes of entities spanning many tables.
- It may not work with optimistic locking. (There are different cases here, depending on how the version is generated.)
- Additionally, since it is stateless, it will not try to regroup same entities class operations to batch them together. As soon as you start another operation (switching from insert to update by example) or start operating on another kind of entities, the previous batch will be flushed. So when operating with stateless session, batching will indeed not work if operations are constantly mixed. It is up to the developer to regroup them.
Seen in your comment on another answer, your entity span many tables. It cannot be batched.
Here is a simplified and incomplete explanation of how it works. The DML batcher works by taking an insert or update or delete command, with parameters for its values. It stores it, along with its parameters values. At the next command it receives, it checks if it matches the previous one. If yes, it stores its parameters values. If it is another command, it flushes the previous batch and stores the new command.
That is why an entity spanning many table cannot be batched: each operation on it implies many commands, causing the batcher to flush at each operation. In some edge cases where you insert a base non-abstract entity not spanning many table then a descendant entity spanning many tables, you may witness the base table insert from the first descendant entity to be batched with the insert of the base entity. But that is a corner case, not actually worth trying to exploit, since it works only for the first many table entity following a base entity operation, and not for following operations.
来源:https://stackoverflow.com/questions/6224583/nhibernate-batch-insert-not-working