More Books
Hibernate: A J2EE Developer's Guide
Hibernate: A J2EE™ Developer's Guide
Table of Contents
Copyright
Acknowledgments
About the Author
Preface
Required Skills
Roadmap
Chapter 1. Overview
Why Object/Relational Mapping?
What Is Hibernate?
Comparing JDBC to Hibernate
Hibernate's Mapping System
Other Java/Database Integration Solutions
How to Obtain and Install
Supported Databases
Chapter 2. Getting Oriented
Application Architecture
Mapping Files
Generating Java Source
Application Configuration
Web Application
JSP Interface
Chapter 3. Starting from Java
Java Object Model
Generated Mapping Files
Generated Schema
Working with Artifacts and Owners
Chapter 4. Starting from an Existing Schema
Initial Schema
Using Middlegen
Generated Mapping Files
Generated Java
Working with the Database
Chapter 5. Mapping Files
Basic Structure
Mapping File Reference
Chapter 6. Persistent Objects
Sessions
Objects and Identity
Life-Cycle Methods
Chapter 7. Relationships
Database Relationships
Java Collection Relationships
Java Class Relationships
Any-Based Relationships
Bi-directional Relationships
Chapter 8. Queries
HQL
HQL Reference
Select
From
Where
Group By
Having
Order By
Criteria Queries
Native SQL Queries
Chapter 9. Transactions
Introduction to Transactions
Optimistic and Pessimistic Locking
Chapter 10. Performance
Finding and Solving Problems
Queries
Inserts
Connection Pooling
Caching
Chapter 11. Schema Management
Updating an Existing Schema
Generating Update and Drop Scripts
Chapter 12. Best Practices, Style Guide, Tips and Tricks
Reducing Code with Inversion of Control
Reducing Session Creation Impact with ThreadLocal
Using Hibernate as an EJB BMP Solution
Integrating with Other Technologies
Applications That Use Hibernate
Strategies for Getting Started
Chapter 13. Future Directions
Hibernate 3.0
EJB 3.0
Here and Now
Index
SYMBOL
A
B
C
D
E
F
G
H
I
J
K
L
M
N
O
P
Q
R
S
T
U
V
W
X

Application Configuration

Given the Java source and a set of mapping files, the application needs code in order to actually perform the needed database operations. A set of Hibernate classes (principally those in the net.sf.hibernate.* package) is used to handle database operations. The initialization() method in Listing 2.7 shows how a Hibernate net.sf.hibernate.cfg.Configuration object is used to create an instance of net.sf.hibernate.SessionFactory.

The net.sf.hibernate.cfg.Configuration object needs a set of mapping files. By using the Configuration.addClass(Object.class) method, Hibernate will search the class path for a directory/*.hbm.xml file that corresponds to the class name. So, given a com.cascadetg.ch02.Author class, Hibernate will look for a com/cascadetg/ch02/Author.hbm.xml file somewhere on the current class path. When the application is run and the Configuration object is first created, Hibernate will verify that the mapping file and the associated Java class files can actually be bound together.

After a successful configuration, Hibernate returns a SessionFactory. A SessionFactory is a thread-safe object intended to be shared throughout the application. Later in this chapter, the application will obtain net.sf.hibernate.Session objects from this SessionFactory.

You may have noticed the reference to net.sf.hibernate.tool.hbm2ddl.SchemaUpdate. This single line of code connects to the database and attempts to create tables, column, and key constraints corresponding to the declared mapping files.

ADVANCED COMMENTS

The code given here attempts to update the schema twice and also issues a MySQL specific command to convert the tables to a format that supports modern database features. For more information, consult the MySQL documentation. If you are using a non-MySQL database, you can comment this functionality out.

Even if you do not intend to use MySQL, it is worth noting that Hibernate allows seamless integration of native SQL functionality. Almost every database includes some vendor-specific capability or optimization. As shown, database-specific functionality fits easily into the overall Hibernate development model. It is up to the individual developer to balance the needs of a portable application against vendor-specific extensions.


Listing 2.7. Hibernate Application Configuration
package com.cascadetg.ch02;

/** Various Hibernate-related imports */
import net.sf.hibernate.*;
import net.sf.hibernate.cfg.*;

import net.sf.hibernate.tool.hbm2ddl.SchemaUpdate;

public class AppSession
{

    static String fileSep =
         System.getProperty("file.separator");

    /** We use this session factory to create our sessions */
    public static SessionFactory sessionFactory;

    public static Session getSession()
    {
        if (sessionFactory == null) initialization();
        try
        {
            return sessionFactory.openSession();
        } catch (Exception e)
        {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * Loads the Hibernate configuration information, sets up the
     * database and the Hibernate session factory.
     */
    public static void initialization()
    {
        try
        {
            Configuration myConfiguration = new
                 Configuration();
            myConfiguration.addClass(Post.class);
            myConfiguration.addClass(Author.class);

            // This is the code that updates the database to the
            // current schema.
            new SchemaUpdate(myConfiguration)
                    .execute(true, true);

            // Sets up the session factory (used in the rest
            // of the application).
            sessionFactory = myConfiguration
                    .buildSessionFactory();

            // MySQL only
            setInnoDB();
            // MySQL only
            new SchemaUpdate(myConfiguration)
                    .execute(true, true);


        } catch (Exception e)
        {
            e.printStackTrace();
        }
    }

    public static void main(String[] args)
    {
        initialization();
    }

    /** MySQL only */
    public static void setInnoDB()
    {
        Session hibernateSession = null;
        Transaction myTransaction = null;

        try
        {
            hibernateSession = sessionFactory.openSession();
            myTransaction =
                 hibernateSession.beginTransaction();

            java.sql.Statement myStatement = hibernateSession
                    .connection().createStatement();
            myStatement
                    .execute("ALTER TABLE Author TYPE=InnoDB");
            myStatement.execute("ALTER TABLE Post
                 TYPE=InnoDB");
            myTransaction.commit();

            System.out.println();
        } catch (Exception e)
        {
            e.printStackTrace();
            try
            {
                myTransaction.rollback();
            } catch (Exception e2)
            {
                // Silent failure of transaction rollback
            }
        } finally
        {
            try
            {
                if (hibernateSession != null)
                        hibernateSession.close();
            } catch (Exception e)
            {
                // Silent failure of session close
            }
        }

    }

}

Using this class to initialize the application makes it easy to port the application to a variety of application servers. The connection underlying the SessionFactory can be set to point to many different data sources, from a JNDI connection to a direct JDBC pool (as described in Chapter 6), and can even add a performance monitor (as described in Chapter 10).

Generated Database Schema

The first time a session is obtained (using the code shown in Listing 2.7), the configuration and SessionFactory are set up and the database schema is updated. Listing 2.8 shows the schema for the tables as generated by this application's mapping files. In particular, note the authorID column, pointing back to the author table.

Listing 2.8. Generated Schema
mysql> desc author;
+-------+--------------+------+-----+---------+-------+
| Field | Type         | Null | Key | Default | Extra |
+-------+--------------+------+-----+---------+-------+
| ID    | varchar(255) |      | PRI |         |       |
| first | varchar(100) | YES  |     | NULL    |       |
| last  | varchar(100) | YES  |     | NULL    |       |
| email | varchar(100) | YES  |     | NULL    |       |
+-------+--------------+------+-----+---------+-------+
4 rows in set (0.11 sec)

mysql> desc post;
+----------+--------------+------+-----+---------+-------+
| Field    | Type         | Null | Key | Default | Extra |
+----------+--------------+------+-----+---------+-------+
| ID       | varchar(255) |      | PRI |         |       |
| revision | int(11)      |      |     | 0       |       |
| title    | varchar(100) | YES  |     | NULL    |       |
| summary  | varchar(255) | YES  |     | NULL    |       |
| content  | text         | YES  |     | NULL    |       |
| date     | datetime     | YES  |     | NULL    |       |
| authorID | varchar(255) |      | MUL |         |       |
+----------+--------------+------+-----+---------+-------+