alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

Hibernate example source code file (batch.xml)

This example Hibernate source code file (batch.xml) is included in the DevDaily.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Java - Hibernate tags/keywords

cdata, customer, customer, for, hibernate, hql, in, java, java, the, the, this, this, transaction

The Hibernate batch.xml source code

<?xml version='1.0' encoding="UTF-8"?>
<!--
  ~ Hibernate, Relational Persistence for Idiomatic Java
  ~
  ~ Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
  ~ indicated by the @author tags or express copyright attribution
  ~ statements applied by the authors.  All third-party contributions are
  ~ distributed under license by Red Hat Middleware LLC.
  ~
  ~ This copyrighted material is made available to anyone wishing to use, modify,
  ~ copy, or redistribute it subject to the terms and conditions of the GNU
  ~ Lesser General Public License, as published by the Free Software Foundation.
  ~
  ~ This program is distributed in the hope that it will be useful,
  ~ but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
  ~ or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
  ~ for more details.
  ~
  ~ You should have received a copy of the GNU Lesser General Public License
  ~ along with this distribution; if not, write to:
  ~ Free Software Foundation, Inc.
  ~ 51 Franklin Street, Fifth Floor
  ~ Boston, MA  02110-1301  USA
  -->

<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
<!ENTITY % BOOK_ENTITIES SYSTEM "../HIBERNATE_-_Relational_Persistence_for_Idiomatic_Java.ent">
%BOOK_ENTITIES;

]>

<chapter id="batch">
    <title>Batch processing
    
    <para>
        A naive approach to inserting 100,000 rows in the database using Hibernate might 
        look like this:
    </para>

<programlisting role="JAVA">

    <para>
        This would fall over with an <literal>OutOfMemoryException somewhere 
        around the 50,000th row. That is because Hibernate caches all the newly inserted 
        <literal>Customer instances in the session-level cache. In this chapter 
	we will show you how to avoid this problem.
    </para>

    <para>
        
        If you are undertaking batch processing you will need to enable the use of
        JDBC batching.  This is absolutely essential if you want to achieve optimal performance.
	Set the JDBC batch size to a reasonable number (10-50, for example):
    </para>
    
<programlisting>

    <para id="disablebatching" revision="1">
        Hibernate disables insert batching at the JDBC level transparently if you
        use an <literal>identity identifier generator.
    </para>

    <para>
        You can also do this kind of work in a process where interaction with 
        the second-level cache is completely disabled:
    </para>

<programlisting>

    <para>
        However, this is not absolutely necessary, since we can explicitly set the
        <literal>CacheMode to disable interaction with the second-level cache.
    </para>

    <section id="batch-inserts">
        <title>Batch inserts

        <para>
            When making new objects persistent <literal>flush() and 
            then <literal>clear() the session regularly in order to control the size of
            the first-level cache.
        </para>

<programlisting role="JAVA">

    </section>

    <section id="batch-update" >
        <title>Batch updates

        <para>
            For retrieving and updating data, the same ideas apply. In addition, you need to 
            use <literal>scroll() to take advantage of server-side cursors for 
            queries that return many rows of data.
        </para>

<programlisting role="JAVA">

    </section>
    
    <section id="batch-statelesssession">
        <title>The StatelessSession interface
        <para>
            Alternatively, Hibernate provides a command-oriented API that can be used for 
            streaming data to and from the database in the form of detached objects. A 
            <literal>StatelessSession has no persistence context associated
            with it and does not provide many of the higher-level life cycle semantics.
            In particular, a stateless session does not implement a first-level cache nor
            interact with any second-level or query cache. It does not implement 
            transactional write-behind or automatic dirty checking. Operations performed
            using a stateless session never cascade to associated instances. Collections 
            are ignored by a stateless session. Operations performed via a stateless session 
            bypass Hibernate's event model and interceptors. Due to the lack of a first-level cache, 
	    Stateless sessions are vulnerable to data aliasing effects. A stateless
            session is a lower-level abstraction that is much closer to the underlying JDBC.
        </para>
        
<programlisting role="JAVA">

        <para>
            In this code example, the <literal>Customer instances returned
            by the query are immediately detached. They are never associated with any persistence
            context.
        </para>
        
        <para>
            The <literal>insert(), update() and delete() operations
            defined by the <literal>StatelessSession interface are considered to be
            direct database row-level operations. They result in the immediate execution of a SQL
            <literal>INSERT, UPDATE or DELETE respectively. 
            They have different semantics to the <literal>save(), saveOrUpdate() 
            and <literal>delete() operations defined by the Session 
            interface.
        </para>

    </section>

    <section id="batch-direct" revision="3">
        <title>DML-style operations

        <para>
            As already discussed, automatic and transparent object/relational mapping is concerned
            with the management of the object state. The object state is available in memory. This means that manipulating data directly in the database (using the SQL <literal>Data Manipulation Language
            (DML) the statements: <literal>INSERT, UPDATE, DELETE)
            will not affect in-memory state. However, Hibernate provides methods
            for bulk SQL-style DML statement execution that is performed through the
            Hibernate Query Language (<link linkend="queryhql">HQL).
        </para>

	    <para>
            The pseudo-syntax for <literal>UPDATE and DELETE statements
            is: <literal>( UPDATE | DELETE ) FROM? EntityName (WHERE where_conditions)?.  
	    </para>

	<para>
	Some points to note:
        </para>

        <itemizedlist spacing="compact">
            <listitem>
                <para>
                    In the from-clause, the FROM keyword is optional
                </para>
            </listitem>
            <listitem>
                <para>
                    There can only be a single entity named in the from-clause. It can, however, be
                    aliased.  If the entity name is aliased, then any property references must
                    be qualified using that alias. If the entity name is not aliased, then it is
                    illegal for any property references to be qualified.
                </para>
            </listitem>
            <listitem>
                <para>
                    No <link linkend="queryhql-joins-forms">joins, either implicit or explicit,
	                can be specified in a bulk HQL query.  Sub-queries can be used in the where-clause, where
	                the subqueries themselves may contain joins.
                </para>
            </listitem>
            <listitem>
                <para>
                    The where-clause is also optional.
                </para>
            </listitem>
        </itemizedlist>

        <para>
            As an example, to execute an HQL <literal>UPDATE, use the
            <literal>Query.executeUpdate() method. The method is named for
            those familiar with JDBC's <literal>PreparedStatement.executeUpdate():
        </para>

<programlisting role="JAVA">

        <para>
            In keeping with the EJB3 specification, HQL <literal>UPDATE statements, by default, do not effect the
            <link linkend="mapping-declaration-version">version
            or the <link linkend="mapping-declaration-timestamp">timestamp property values
            for the affected entities. However,
            you can force Hibernate to reset the <literal>version or
            <literal>timestamp property values through the use of a versioned update.
            This is achieved by adding the <literal>VERSIONED keyword after the UPDATE
            keyword.
        </para>
<programlisting role="JAVA">

        <para>
            Custom version types, <literal>org.hibernate.usertype.UserVersionType,
            are not allowed in conjunction with a <literal>update versioned statement.
        </para>

        <para>
            To execute an HQL <literal>DELETE, use the same Query.executeUpdate()
            method:
        </para>

<programlisting role="JAVA">

        <para>
            The <literal>int value returned by the Query.executeUpdate()
            method indicates the number of entities effected by the operation.  This may or may not
            correlate to the number of rows effected in the database.  An HQL bulk operation might result in
            multiple actual SQL statements being executed (for joined-subclass, for example).  The returned
            number indicates the number of actual entities affected by the statement.  Going back to the
            example of joined-subclass, a delete against one of the subclasses may actually result
            in deletes against not just the table to which that subclass is mapped, but also the "root"
            table and potentially joined-subclass tables further down the inheritance hierarchy.
        </para>

        <para>
            The pseudo-syntax for <literal>INSERT statements is:
            <literal>INSERT INTO EntityName properties_list select_statement.  Some
            points to note:
        </para>

        <itemizedlist spacing="compact">
            <listitem>
                <para>
                    Only the INSERT INTO ... SELECT ... form is supported; not the INSERT INTO ... VALUES ... form.
                </para>
                <para>
                    The properties_list is analogous to the <literal>column specification
                    in the SQL <literal>INSERT statement.  For entities involved in mapped
                    inheritance, only properties directly defined on that given class-level can be
                    used in the properties_list.  Superclass properties are not allowed and subclass
                    properties do not make sense.  In other words, <literal>INSERT
                    statements are inherently non-polymorphic.
                </para>
            </listitem>
            <listitem>
                <para>
                    select_statement can be any valid HQL select query, with the caveat that the return types
                    must match the types expected by the insert.  Currently, this is checked during query
                    compilation rather than allowing the check to relegate to the database. 
                    This might, however, cause problems between Hibernate <literal>Types which are
                    <emphasis>equivalent as opposed to equal.  This might cause
                    issues with mismatches between a property defined as a <literal>org.hibernate.type.DateType
                    and a property defined as a <literal>org.hibernate.type.TimestampType, even though the
                    database might not make a distinction or might be able to handle the conversion.
                </para>
            </listitem>
            <listitem>
                <para>
                    For the id property, the insert statement gives you two options.  You can either
                    explicitly specify the id property in the properties_list, in which case its value
                    is taken from the corresponding select expression, or omit it from the properties_list,
                    in which case a generated value is used.  This latter option is only available when
                    using id generators that operate in the database; attempting to use this option with
                    any "in memory" type generators will cause an exception during parsing.  
                    For the purposes of this discussion, in-database generators are considered to be
                    <literal>org.hibernate.id.SequenceGenerator (and its subclasses) and
                    any implementers of <literal>org.hibernate.id.PostInsertIdentifierGenerator.
                    The most notable exception here is <literal>org.hibernate.id.TableHiLoGenerator,
                    which cannot be used because it does not expose a selectable way to get its values.
                </para>
            </listitem>
            <listitem>
                <para>
                    For properties mapped as either <literal>version or timestamp,
                    the insert statement gives you two options.  You can either specify the property in the
                    properties_list, in which case its value is taken from the corresponding select expressions,
                    or omit it from the properties_list, in which case the <literal>seed value defined
                    by the <literal>org.hibernate.type.VersionType is used.
                </para>
            </listitem>
        </itemizedlist>

        <para>
            The following is an example of an HQL <literal>INSERT statement execution:
        </para>

<programlisting role="JAVA">

    </section>

</chapter>

Other Hibernate examples (source code examples)

Here is a short list of links related to this Hibernate batch.xml source code file:

... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.