<?xml version='1.0' encoding='utf-8' ?>

<!--
  ~ Hibernate, Relational Persistence for Idiomatic Java
  ~
  ~ License: GNU Lesser General Public License (LGPL), version 2.1 or later.
  ~ See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
  -->
<chapter xml:id="batch"
         xmlns="http://docbook.org/ns/docbook"
        >
    <title>Batching</title>

    <para>
        First we need to decide what all to discuss here as that phrase has so many connotations. Do we cover
        <itemizedlist>
            <listitem>JDBC batch updates?</listitem>
            <listitem>Session w/ incremental flushing?</listitem>
            <listitem>StatelessSession?</listitem>
            <listitem>Java EE batching?</listitem>
            <listitem>Any/all of the above?</listitem>
            <listitem>Others?</listitem>
        </itemizedlist>
    </para>

    <section xml:id="batch-jdbcbatch">
        <title>JDBC batching</title>

        <para>
            JDBC offers support for batching together SQL statements that can be represented
            as a single PreparedStatement.  Implementation wise this generally means that drivers
            will send the batched operation to the server in one call, which can save on network calls
            to the database.  Hibernate can leverage JDBC batching.  The following settings control this
            behavior.
        </para>

        <itemizedlist>
            <listitem>
                <para>
                    <literal>hibernate.jdbc.batch_size</literal> - Controls the maximum number of
                    statements Hibernate will batch together before asking the driver to execute
                    the batch.  Zero or a negative number disables this feature.
                </para>
            </listitem>
            <listitem>
                <para>
                    <literal>hibernate.jdbc.batch_versioned_data</literal> - Some JDBC drivers
                    return incorrect row counts when a batch is executed.  If your JDBC driver
                    falls into this category this setting should be set to <literal>false</literal>.
                    Otherwise it is safe to enable this which will allow Hibernate to still
                    batch the DML for versioned entities and still use the returned row counts for
                    optimitic lock checks.  Currently defaults to false to be safe.
                </para>
            </listitem>
            <listitem>
                <para>
                    <literal>hibernate.jdbc.batch.builder</literal> - Names the implementation class
                    used to manage batching capabilities.  It is almost never a good idea to switch from
                    Hibernate's default implementation.  But if you wish to, this setting would name the
                    <interfacename>org.hibernate.engine.jdbc.batch.spi.BatchBuilder</interfacename>
                    implementation to use.
                </para>
            </listitem>
            <listitem>
                <para>
                    <literal>hibernate.order_updates</literal> - Forces Hibernate to order SQL updates by the
                    entity type and the primary key value of the items being updated. This allows for more batching
                    to be used.  It will also result in fewer transaction deadlocks in highly concurrent systems.
                    Comes with a performance hit, so benchmark before and after to see if this actually helps or
                    hurts your application.
                </para>
            </listitem>
            <listitem>
                <para>
                    <literal>hibernate.order_inserts</literal> - Forces Hibernate to order inserts to allow for
                    more batching to be used.  Comes with a performance hit, so benchmark before and after to see
                    if this actually helps or hurts your application.
                </para>
            </listitem>
        </itemizedlist>
    </section>
</chapter>