Chapter 1. Installation and Setup
It continues to amaze me how many great, free, open source Java™ tools are out there. When I needed a lightweight object/relational mapping service for a JSP e-commerce project at the turn of the millennium, I had to build my own. It evolved over the years, developed some cool and unique features, and we’ve used it in a wide variety of different contexts. But, once I discovered Hibernate, we used that for new development instead of my own familiar system (toward which I’ll cheerfully admit bias). That should tell you how compelling it is!
If you’re looking at this book, you’re likely interested in a powerful and convenient way to bridge the worlds of Java objects and relational databases. Hibernate fills that role very nicely, without being so complicated that learning it becomes a daunting challenge in itself. To demonstrate that, this chapter guides you to the point where you can play with Hibernate and see for yourself why it’s so exciting.
Later chapters will look at using Hibernate as part of more complex environments such as Spring and Stripes, as well as using it with other databases. The goal of this first chapter is to show you how easy it is to put together a basic, self-contained environment in which you can explore Hibernate and do real things with it.
Getting an Ant Distribution
Although it might be surprising, the first few things you need to get Hibernate running have nothing to do with Hibernate itself. First, you must set up an environment in which the remaining examples work. This will have the pleasant side effect of building a solid foundation for any actual project you might be undertaking.
If you’re not already using Ant to manage the building, testing, running, and packaging of your Java projects, now is the time to start. The examples in this book are Ant-driven, so you’ll need a working Ant installation to run them and experiment with variations on your own system, which is the best way to learn.
First of all, get an Ant binary and install it.
Why do I care?
The examples use Apache Ant for several reasons. It’s convenient and powerful; it’s one of the standard build tools for Java-based development; it’s free; and it’s cross-platform. If you use Ant, the examples will work equally well anywhere there’s a Java environment, which means readers of this book won’t be frustrated or annoyed. Fortunately, it also means we can do many more cool things with less effort—especially since several Hibernate tools have explicit Ant support, which I’ll show you how to leverage. (I should note that these days more complex Java projects often use Maven, which adds many other project management capabilities. Since I had to pick one, in the spirit of keeping things simple and true to what I find useful, I went with Ant for these examples.)
If you are currently using Maven as a build tool, you will notice that we are using Maven’s Ant Tasks to manage dependencies from our Ant builds. Although Maven is gaining momentum, Ant continues to be the most widely used build tool in Java development. Every chapter’s example code folder also has a Maven pom.xml file and can be compiled with Maven. In many cases, the Maven build file provides the same functionality as the Ant build.xml file by using the Maven Hibernate3 plug-in. In Chapter 12 you will find some guidance for building and deploying Hibernate applications using full-blown Maven, but the majority of the examples in this book focus on Ant as a build tool, using the Maven Ant Tasks to relieve the tedium of finding and downloading the various libraries we need, and the libraries on which they, in turn, rely.
To take advantage of all these capabilities, you need to have Ant installed and working on your system.
Note
I used to wonder why people bothered with Ant when they could use Make. Now that I’ve seen how well Ant manages Java builds, I feel lost without it.
How do I do that?
You can download a binary release of Ant from http://ant.apache.org/bindownload.cgi. Scroll down to
find the current release of Ant, and download the archive in a format
that’s convenient for you to work with. Pick an appropriate place for it
to live, and expand the archive there. The directory into which you’ve
expanded the archive is referred to as ANT_HOME
.
Let’s say you’ve expanded the archive into the directory /usr/local/apache-ant-1.7.0; you may want to
create a symbolic link to make it easier to work with and to avoid the
need to change any environment configuration when you upgrade to a newer
version:
/usr/local %
ln -s apache-ant-1.7.0 ant
Once Ant is situated, you need to do a couple of things to make it
work correctly. You need to add its bin directory in the distribution (in this
example, /usr/local/ant/bin) to
your command path. You also need to set the environment variable
ANT_HOME
to the top-level directory you installed (in
this example, /usr/local/ant).
Details about how to perform these steps under different operating
systems can be found in the Ant manual (http://ant.apache.org/manual/) if you need
them.
Check Your Java Version
Of course, I’m also assuming you’ve got a Java software development kit (SDK). These days you should be using Java 5 at the very least, since it gives you some useful new language features. Go with the most recent stable SDK if you can. Either Java 5 or Java 6 should work with all of the examples in this book. It was possible to use most of Hibernate 2 with Java 1.3, but you generally had to rebuild the Hibernate JAR file using your 1.3 compiler. We can only imagine more recent releases depend even more strongly on current Java versions, and Java 5 has been out long enough, and has enough benefits of its own, that we’re not even going to investigate compatibility with prior JDKs. Our examples are written assuming you’ve got at least Java 5—and will need some serious tweaking if you don’t:
%
java -version
java version "1.6.0_02"
Java(TM) SE Runtime Environment (build 1.6.0_02-b06)
Java HotSpot(TM) Client VM (build 1.6.0_02-b06, mixed mode, sharing)
You should also be using a real licensed Java distribution (such as those from Sun or Apple); our technical reviewers found that the GNU “workalike” implementation did not run these tools and examples properly at the time of this writing. This GNU environment is the default Java shipped with many Linux distributions. If you’re working with a Linux distribution, you may need to download Sun’s JDK yourself and make sure it’s the version you’re invoking (by running java -version). Now that Sun has open sourced Java, this will hopefully improve in the future, and we’ll get the Sun JRE and JDK by default even in purist distributions. Until that day, you may need to do some of your own downloading.
Tip
At the time of this writing, Debian-based distributions allow you to install a Sun JDK using their package management utilities (both 5 and 6 are available in Ubuntu’s “Feisty Fawn” and “Gutsy Gibbon” releases). Red Hat–derived distributions still need to download Java directly from Sun Microsystems. Your mileage may vary.
Once you’ve got all this set up, you should be able to fire up Ant for a test run and verify that everything’s right:
%
ant -version
Apache Ant version 1.7.0 compiled on December 13 2006
What just happened?
Well, not much just yet, but you’re now in a position where you’ll be able to try out the examples we provide later on, and use them as a starting point for your actual Hibernate projects.
If you’re new to Ant, it wouldn’t be a bad idea to read the manual
a little bit to get a sense of how it works and what it can do for you;
this will help make sense of the build.xml
files we start working
with in our examples. If you decide (or already know) you like Ant, and
want to dig deeper, you can read the manual or pick up O’Reilly’s
Ant: The Definitive Guide (after you
finish this book, of course)!
What about…
…Eclipse, JBuilder, NetBeans, or some other Java IDE? Well, you can certainly use these, but you’re on your own as far as what you need to do to get Ant integrated into the build process. (Several already use Ant, so you might be starting out ahead; for the others, you might have to jump through some hoops.) If all else fails, you can use the IDE to develop your own code but invoke Ant from the command line when you need to use one of our build scripts.
Tip
If you are using Maven, you can generate Eclipse IDE project files by executing mvn eclipse:eclipse from any chapter’s example directory, or in the top-level examples directory. If you run mvn eclipse:eclipse from the examples directory, Maven will generate an Eclipse project for each chapter’s example set. In Chapter 12 you will find a more detailed recipe for building the examples in Maven, and Chapter 11 is an introduction to using Hibernate’s Eclipse Tools more thoroughly.
Getting the Maven Tasks for Ant
Wait—didn’t I just finish telling you that we’re using Ant for the example projects in this book? I did. But that wasn’t the whole story. Although Ant remains the foundation for the examples in this book, we’ve decided in this second version also to leverage Maven’s excellent dependency management features via the Maven Tasks for Ant. The initial version of this book spent precious pages providing instructions for downloading and arranging a whole host of third-party libraries: everything from Jakarta Commons Lang to CGLIB. (And from your perspective, it meant you had to spend many precious minutes carefully and tediously following those instructions.) In this version, we’re declaring our project’s dependencies in our build.xml file and letting Maven take care of downloading and managing our dependencies. This saves a ton of steps and time. Now it’s time to install the Maven Tasks for Ant.
How do I do that?
There are two ways to integrate the Maven Tasks for Ant: the first
is to drop the required JAR in Ant’s lib directory, and the second is to include
the antlib via a typedef
declaration
in an Ant build file. We’re going to use the former method, and drop the
maven-ant-tasks-2.0.8.jar into
Ant’s lib
directory because it requires the least amount of work in our example’s
build.xml file, and makes it easier
to share between multiple projects. We’ll get to creating build.xml later. First, let’s download the necessary JAR file from the
Maven web site. On the
front page you should see a link to download Maven Tasks for Ant (see Figure 1-1).
At the time of this writing, the Maven Tasks for Ant are at version 2.0.8. Clicking on the Maven Tasks for Ant 2.0.8 link and choosing a mirror will download a JAR file named maven-ant-tasks-2.0.8.jar. Save this file to a local directory.
Installing the Maven Tasks for Ant
Next, copy the maven-ant-tasks-2.0.8.jar file that you just downloaded to your ANT_HOME/lib directory. If
you are following this chapter from start to finish, you just downloaded
and installed Ant. You also should have set the environment variable
ANT_HOME
, and you should be familiar with where you just installed
Ant. Once you’ve copied the maven-ant-tasks-2.0.8.jar to your ANT_HOME/lib directory, any
build.xml file can include the
appropriate namespace to use the Maven Tasks for Ant.
Tip
If you are running these examples on a multiuser development machine, and you don’t have administrative rights to put a JAR file into the ANT_HOME/lib directory, don’t worry. You can put the maven-ant-tasks-2.0.8.jar file in the ~/.ant/lib directory. Ant will also automatically look for any JAR files in this directory.
Once you’ve copied the maven-ant-tasks-2.0.8.jar to your ANT_HOME/lib directory, you should be able to run the following command to see if maven-ant-tasks-2.0.8.jar is included in the class path on Unix:
%
ant -diagnostics | grep maven | grep bytes
maven-ant-tasks-2.0.8.jar (960232 bytes)
In Windows, run ant -diagnostics and inspect the output for the presence of maven-ant-tasks-2.0.8.jar in the list of libraries on the class path.
Using the HSQLDB Database Engine
Hibernate works with a great many relational databases; chances are, it will work with the one you are planning to use for your next project. We need to pick one to focus on in our examples, and luckily there’s an obvious choice. The free, open source, 100% Java HSQLDB project is powerful enough that it forms the backing storage for several of our commercial software projects. Surprisingly, it’s also incredibly self-contained and simple to install—so easy, in fact, that we can let Maven take care of it for us in this new version of the book—so it’s perfect to discuss here. (If you’ve heard of Hypersonic-SQL, this is its current incarnation. Much of the Hibernate documentation uses the older name.)
Tip
Don’t panic if you stumble across http://hsql.sourceforge.net/ and it seems like the project has been shut down. That’s the wrong address; it’s talking about the predecessor to the current HSQLDB project. Figure 1-2 shows the correct home page of the current, quite lively project.
Why do I care?
Examples based on a database that everyone can download and easily experiment with mean you won’t have to translate any of our SQL dialects or operating system commands to work with your available databases (and may even mean you can save a day or two learning how to download, install, and configure one of the more typical database environments). Finally, if HSQLDB is new to you, chances are good you’ll be impressed and intrigued, and you may well end up using it in your own projects. As it says on the project home page:
HSQLDB is the leading SQL relational database engine written in Java. It has a JDBC driver and supports a rich subset of ANSI-92 SQL (BNF tree format) plus SQL 99 and 2003 enhancements. It offers a small (less than 100 k in one version for applets), fast database engine which offers both in-memory and disk-based tables and supports embedded and server modes. Additionally, it includes tools such as a minimal web server, in-memory query and management tools (can be run as applets), and a number of demonstration examples.
How do I do that?
When you build the examples in this book, the Maven Ant Tasks will automatically download the HSQLDB JARs (and any other JARs you need) from the Maven repository at http://repo1.maven.org/maven2/. So if you want to just get right to playing, you can skip ahead to Setting Up a Project Hierarchy.” On the other hand, if you would like to download HSQLDB for your own purposes or to explore the documentation, online forum, or mailing list archives, visit the project page at http://hsqldb.org/. Click the link to manually download the “latest stable version” (which is 1.8.0.7 at the time of this writing, as highlighted in Figure 1-2). This will take you to a typical SourceForge downloads page with the current release selected. Pick your mirror and download the ZIP archive.
Note
Go on, download HSQLDB. Heck, take two, they’re small!
What about…
…some other common database? Don’t worry, Hibernate can work with MySQL, PostgreSQL, Oracle, DB2, Sybase, Informix, Apache Derby, and others. (We’ll talk about how you specify “dialects” for different databases later on, in Chapter 10 and Appendix C.) And, if you really want, you can try to figure out how to work with your favorite from the start, but it will mean extra work for you in following along with the examples, and you’ll miss out on a great opportunity to discover HSQLDB.
Using Hibernate Core
This section doesn’t need much motivation! You picked up this book because you wanted to learn how to use Hibernate. The part that provides core object/relational mapping services for your applications is called, perhaps not too surprisingly, Hibernate Core. When you build the examples in this book, Hibernate and all of its dependencies are downloaded automatically. Even though this new version of the book’s examples take care of getting Hibernate through the Maven Ant Tasks, you might want to download the latest Hibernate distribution yourself to explore the source, or just view the online documentation, forum, and other support materials. If you’re ready to dive in to trying things out instead, you can skip to the next section, Setting Up a Project Hierarchy.”
How do I do that?
Start at the Hibernate home page at http://hibernate.org/ and explore from there. To get a complete copy of the distribution, find the Download link, which is on the left side as shown in Figure 1-3.
The Binary Releases section will tell you which version of Hibernate Core is recommended for downloading; follow that advice. (If you want to be brave, you can try a Development release, but the safest bet is to stick with the latest Production version.) Once you’ve made your choice, click the Download link in the corresponding row (see Figure 1-4).
This takes you to a SourceForge downloads page containing your
chosen release, in a choice of archive formats. Pick your favorite and
download it. The filename will look something like hibernate-3.x
.y
.tar.gz
or hibernate-3.x
.y
.zip.
(At the time of this writing, the filenames start with hibernate-3.2.5.ga, since the first generally
available release of Hibernate 3.2.5 is the current production
release.)
Pick a place that is suitable for keeping such items and expand the archive.
While you’re on the
Hibernate downloads page, you may also want to look at the
Hibernate Tools (the Download link takes you to a page titled JBoss
Tools, but you can still find the Hibernate Tools there). They offer
several useful capabilities that aren’t necessary for an application
running Hibernate but are very helpful for developers creating such
applications. We’ll be using one to generate Java code for our first
Hibernate experiment shortly. The Tools filename will look like
hibernatetools-3.x
.y
.zip
(it won’t necessarily have the same version as Hibernate itself and
seems usually to be available only as a beta; the Compatibility Matrix
right below the Binary Releases section of Hibernate’s downloads page
displays a table showing which Hibernate pieces are compatible with each
other).
Once again, download this file and expand it next to where you put Hibernate.
Tip
If you have trouble with the download links, the site may be in a state of flux, and you may not see the files you expect. If that happens, you can fall back to clicking the “Browse all Hibernate downloads” link below the Binary Releases box and scroll through until you find what you’re looking for. The project is so active that this happens more often than you might expect.
Setting Up a Project Hierarchy
Although we’re going to start small in this walk-through, once we begin designing data structures and building Java classes and database tables that represent them, along with all the configuration and control files to glue them together and make useful things happen, we’re going to end up with a lot of files. So, we want to make certain we are very organized from the beginning. Between the tools we’ve downloaded and their supporting libraries, there are already a significant number of files to organize. Luckily for us, the Maven Ant Tasks download and manage all of our external dependencies.
Why do I care?
If you end up building something cool by extending the examples in this book, and want to turn it into a real application, you’ll be in good shape from the beginning. More to the point, if you set things up the way we describe here, the commands and instructions we give you throughout the examples will make sense and actually work; many examples build on one another throughout the book, so it’s important to get on the right track from the beginning.
If you want to skip ahead to a later example, or just avoid typing some of the longer sample code and configuration files, you can download “finished” versions of the chapter examples from the book’s web site. These downloads will all be organized as described here. We strongly recommend that you download the examples and use them as a reference while you read this book.
How do I do that?
Here’s how to set up an empty project hierarchy if you’re not downloading the “finished” examples:
Pick a location on your hard drive where you want to work through these examples, and create a new folder, which we’ll refer to from now on as your project directory.
Move into that directory, and create subdirectories called src and data. The hierarchy of Java source and related resources will be in the src directory. Our build process will compile it into a classes directory it creates, as well as copy any runtime resources there. The data directory is where we’ll put the HSQLDB database.
The example classes we’re going to create are all going to live in the
com.oreilly.hh
(harnessing Hibernate) package, and we’ll have Hibernate generate our data beans in the com.oreilly.hh.data package to keep them separate from classes we write by hand, so create these directories under the src directory. On Linux and Mac OS X, you can use:mkdir -p src/com/oreilly/hh/data
from within your project directory to accomplish this in one step.
At this point, your project directory should be structured as shown in Figure 1-5.
Note
This is so much simpler than it was in the first book that it’s almost not worth showing!
A quick test
Before we get into actually rousing Hibernate to do some useful work, it’s worth checking that the other supporting pieces are in place and ready to use. Let’s start the Ant configuration file we’ll be using throughout this project, tell Ant where we’ve put the files we’re using, and have it fire up the HSQLDB graphical database interface. This will prove that the Maven Ant Tasks are able to find and download the libraries on which the examples will rely, and the ability to access the interface will be useful later when we want to look at the actual data that Hibernate has been creating for us. For the moment this is primarily a sanity check that nothing is amiss and we’re ready to move forward.
Fire up your favorite text editor, and create a file named build.xml at the top level inside your project directory. Type the content of Example 1-1 into the file.
<?xml version="1.0"?> <project name="Harnessing Hibernate 3 (Developer's Notebook Second Edition)" default="db" basedir="." xmlns:artifact="antlib:org.apache.maven.artifact.ant"> <!-- Set up properties containing important project directories --> <property name="source.root" value="src"/> <property name="class.root" value="classes"/> <property name="data.dir" value="data"/> <artifact:dependencies pathId="dependency.classpath"> <dependency groupId="hsqldb" artifactId="hsqldb" version="1.8.0.7"/> <dependency groupId="org.hibernate" artifactId="hibernate" version="3.2.5.ga"> <exclusion groupId="javax.transaction" artifactId="jta"/> </dependency> <dependency groupId="org.hibernate" artifactId="hibernate-tools" version="3.2.0.beta9a"/> <dependency groupId="org.apache.geronimo.specs" artifactId="geronimo-jta_1.1_spec" version="1.1"/> <dependency groupId="log4j" artifactId="log4j" version="1.2.14"/> </artifact:dependencies> <!-- Set up the class path for compilation and execution --> <path id="project.class.path"> <!-- Include our own classes, of course --> <pathelement location="${class.root}" /> <!-- Add the dependencies classpath --> <path refid="dependency.classpath"/> </path> <target name="db" description="Runs HSQLDB database management UI against the database file--use when application is not running"> <java classname="org.hsqldb.util.DatabaseManager" fork="yes"> <classpath refid="project.class.path"/> <arg value="-driver"/> <arg value="org.hsqldb.jdbcDriver"/> <arg value="-url"/> <arg value="jdbc:hsqldb:${data.dir}/music"/> <arg value="-user"/> <arg value="sa"/> </java> </target> </project>
Tip
Take care with punctuation if you’re typing this, and pay special attention to self-closing XML tags (those which end in “/>” rather than just “>”). If you get it wrong, you’ll be rewarded with parse errors when you run Ant. Again, you can download all these files if you don’t need the typing practice. If you’re viewing this as a PDF on-screen, you can also cut and paste the code, but you will need to edit out the numbered callout bullets.
If you haven’t seen an Ant build file before, here’s a whirlwind introduction to help orient you. The documentation at http://ant.apache.org/manual/index.html is quite good if you want a bit more detail:
The first line is simply a declaration that the type of the file is XML. If you’ve worked with XML in other contexts, you’re used to seeing this. If not, you’ll see it again. (Ant doesn’t currently require this, but most XML parsers do, so it’s a good habit to develop.)
Ant’s build files always contain a single
project
definition. Thedefault
attribute tells Ant which target (defined later) to build if you don’t specify any on the command line. And thebasedir
attribute determines the directory relative to which all path calculations are done. We could have left this out since the default is to treat paths as being relative to the directory in which the build.xml is located, but it’s a good habit to be explicit about fundamental settings like this. An important thing to note in thisproject
element is thexmlns:artifact
namespace definition for the Maven Ant Tasks. This namespace definition makes the Maven Ant Tasks available within this build file using theartifact:
prefix (as you’ll see used later).The next bit defines three properties that we can use by name throughout the rest of the build file. Essentially, we’re defining symbolic names for the important directories used for different aspects of the project. This isn’t necessary (especially when the directories are named so simply), but it’s another good practice. For one thing, it means that if you need to change where one of these directories is located, you need to fix only one place in the build file, rather than conducting a tedious search and replace.
The
artifact:dependencies
element is from the Maven Ant Tasks, which you (and Ant) can tell by theartifact:
prefix. In this element we are defining a set of dependencies which the project needs for compilation and execution. These dependencies correspond to JAR files (or artifacts) in the central Maven 2 Repository at http://repo1.maven.org/maven2. Each artifact is uniquely identified by agroupId
,artifactId
, and aversion
number. In this project, we’re depending on Hibernate, HSQLDB, Log4J, and the JTA API. When the Maven Ant Tasks encounter these dependency declarations, each artifact is downloaded from the central Maven 2 repository on an as-needed basis to your local Maven 2 repository (in ~/.m2/repository). Don’t worry if this section doesn’t make much sense just yet; we’re going to delve deeper into the details in a few pages.This section is where you’d make changes to use a more recent version of one of these packages if you wanted to (since newer versions will likely become available after this book is printed), by changing the
version
values. But you can be confident the examples as printed in the book will continue to work, since the Maven repository guarantees the versions we tested against will continue to be available whenever you’re exploring the examples. This in itself was a big reason we decided to adopt the Maven Ant Tasks for this book.The
class-path
section serves a clear purpose. This feature alone is why I almost never start Java projects anymore without setting up at least a simple Ant build for them. When you’re using a lot of third-party libraries, which you’re going to be doing for any serious project, there’s a whole lot that needs to go into your class path, and you have to be sure to set it equivalently at compile time and runtime. Ant makes this very easy. We define a path, which is kind of like a property, but it knows how to parse and collect files and directories. Our path contains the classes directory in which we’re going to be compiling our Java source (this directory doesn’t exist yet; we’ll add a step to the build process to create it in the next chapter), and it also contains all JAR files corresponding to the dependencies listed in theartifact:dependencies
element. This is exactly what we need for compiling and running.Tip
Ant’s understanding and manipulation of Java paths and class hierarchies is a big plus. It’s worth learning in some depth.
The syntax on this line looks like punctuation soup but can be broken down into pieces that make sense. Ant lets you use substitution to insert variable values into your rules. Where you see something like
"${class.root}"
, this means “look up the value of the property namedclass.root
and stick it here.” So, given the definition of theclass.root
property earlier, it’s as if we had typed:<pathelement location="classes"/>
. So, why do this? It lets you share a value throughout the file, so if you ever need to change it, there’s only one place to worry about. In large, complex projects, this kind of organization and management is crucial.The
artifact:dependencies
element we saw earlier assembled all of the declared dependencies into a single path nameddependency.classpath
using itspathId
attribute. Here, we are appending the contents ofdependency.classpath
to theproject.class.path
so all our Maven-fetched dependencies are available at compilation and runtime.Finally, with all this preamble out of the way, we can define our first target. A target is just a series of tasks that need to be executed in order to accomplish a project goal. Typical targets do things like compile code, run tests, package things up for distribution, and the like. Tasks are chosen from a rich set of capabilities built into Ant, and third-party tools like Hibernate can extend Ant to provide their own useful tasks, as we’ll see in the next chapter. Our first target,
db
, is going to run HSQLDB’s graphical interface so we can look at our example database. We can accomplish that using Ant’s built-injava
task, which can run a Java virtual machine for us, with whatever starting class, arguments, and properties we’d like.In this case, the class we want to invoke is
org.hsqldb.util.DatabaseManager
, found in the HSQLDB JAR that the Maven Ant Tasks will manage for us. Setting thefork
attribute toyes
tells Ant to use a separate virtual machine, which isn’t the default since it takes a little longer and isn’t usually necessary. In this case, it’s important since we want the database manager GUI to stay around until we dismiss it, and this doesn’t happen when it runs in Ant’s own VM.Tip
If your database GUI pops up and vanishes, double-check the
fork
attribute of yourjava
task.You can see how we’re telling the
java
task about the class path we’ve set up; this will be a common feature of our targets. Then we supply a bunch of arguments to the database manager, telling it to use the normal HSQLDB JDBC driver, where to find the database, and what username to use. We’ve specified a database calledmusic
in thedata
directory. That directory is currently empty, so HSQLDB will create the database the first time we use it. The usersa
is the default “system administrator” user for new databases, and it’s configured not to need a password initially. Obviously, if you plan to make this database available over the network (which HSQLDB is capable of doing), you’ll want to set a password. We aren’t doing any such fancy things, so we can leave that out for now.
OK, let’s try it! Save the file, and from a shell (command) prompt running in your top-level project directory (where you put build.xml), type the command:
ant db
(Or, since we’ve made db
the
default target, you can just type ant.) Once Ant starts running, if all goes
well, you’ll see output like this:
Buildfile: build.xml Downloading: hsqldb/hsqldb/1.8.0.7/hsqldb-1.8.0.7.pom Transferring 0K Downloading: org/hibernate/hibernate/3.2.5.ga/hibernate-3.2.5.ga.pom Transferring 3K Downloading: net/sf/ehcache/ehcache/1.2.3/ehcache-1.2.3.pom Transferring 19K Downloading: commons-logging/commons-logging/1.0.4/commons-logging-1.0.4.pom Transferring 5K Downloading: commons-collections/commons-collections/2.1/commons-collections-2.1 .pom Transferring 3K Downloading: asm/asm-attrs/1.5.3/asm-attrs-1.5.3.pom Transferring 0K Downloading: dom4j/dom4j/1.6.1/dom4j-1.6.1.pom Transferring 6K Downloading: antlr/antlr/2.7.6/antlr-2.7.6.pom Transferring 0K Downloading: cglib/cglib/2.1_3/cglib-2.1_3.pom Transferring 0K Downloading: asm/asm/1.5.3/asm-1.5.3.pom Transferring 0K Downloading: commons-collections/commons-collections/2.1.1/commons-collections-2 .1.1.pom Transferring 0K Downloading: org/hibernate/hibernate-tools/3.2.0.beta9a/hibernate-tools-3.2.0.be ta9a.pom Transferring 1K Downloading: org/hibernate/hibernate/3.2.0.cr5/hibernate-3.2.0.cr5.pom Transferring 3K Downloading: freemarker/freemarker/2.3.4/freemarker-2.3.4.pom Transferring 0K Downloading: org/hibernate/jtidy/r8-20060801/jtidy-r8-20060801.pom Transferring 0K Downloading: org/apache/geronimo/specs/geronimo-jta_1.1_spec/1.1/geronimo-jta_1. 1_spec-1.1.pom Transferring 1K Downloading: org/apache/geronimo/specs/specs/1.2/specs-1.2.pom Transferring 2K Downloading: org/apache/geronimo/genesis/config/project-config/1.1/project-confi g-1.1.pom Transferring 14K Downloading: org/apache/geronimo/genesis/config/config/1.1/config-1.1.pom Downloading: org/apache/geronimo/genesis/config/config/1.1/config-1.1.pom Downloading: org/apache/geronimo/genesis/config/config/1.1/config-1.1.pom Transferring 0K Downloading: org/apache/geronimo/genesis/genesis/1.1/genesis-1.1.pom Downloading: org/apache/geronimo/genesis/genesis/1.1/genesis-1.1.pom Downloading: org/apache/geronimo/genesis/genesis/1.1/genesis-1.1.pom Transferring 6K Downloading: org/apache/apache/3/apache-3.pom Downloading: org/apache/apache/3/apache-3.pom Downloading: org/apache/apache/3/apache-3.pom Transferring 3K Downloading: log4j/log4j/1.2.14/log4j-1.2.14.pom Transferring 2K Downloading: org/hibernate/hibernate-tools/3.2.0.beta9a/hibernate-tools-3.2.0.be ta9a.jar Transferring 352K Downloading: org/hibernate/jtidy/r8-20060801/jtidy-r8-20060801.jar Transferring 243K Downloading: commons-collections/commons-collections/2.1.1/commons-collections-2 .1.1.jar Transferring 171K Downloading: commons-logging/commons-logging/1.0.4/commons-logging-1.0.4.jar Transferring 37K Downloading: antlr/antlr/2.7.6/antlr-2.7.6.jar Transferring 433K Downloading: org/apache/geronimo/specs/geronimo-jta_1.1_spec/1.1/geronimo-jta_1. 1_spec-1.1.jar Transferring 15K Downloading: net/sf/ehcache/ehcache/1.2.3/ehcache-1.2.3.jar Transferring 203K Downloading: asm/asm/1.5.3/asm-1.5.3.jar Transferring 25K Downloading: freemarker/freemarker/2.3.4/freemarker-2.3.4.jar Transferring 770K Downloading: dom4j/dom4j/1.6.1/dom4j-1.6.1.jar Transferring 306K Downloading: asm/asm-attrs/1.5.3/asm-attrs-1.5.3.jar Transferring 16K Downloading: cglib/cglib/2.1_3/cglib-2.1_3.jar Transferring 275K Downloading: hsqldb/hsqldb/1.8.0.7/hsqldb-1.8.0.7.jar Transferring 628K Downloading: log4j/log4j/1.2.14/log4j-1.2.14.jar Transferring 358K Downloading: org/hibernate/hibernate/3.2.5.ga/hibernate-3.2.5.ga.jar Transferring 2202K db:
This big list of downloads shows the Maven Ant Tasks doing their job of finding the pieces we told them we needed (including HSQLDB and Hibernate), along with all the libraries on which they, in turn, depend. This takes a little while to accomplish (depending on how fast your network connection is, and how loaded the servers are), but it will only need to happen once. The next time you fire up Ant, the Maven Ant Tasks will simply notice that your local repository already contains all these pieces, and will silently proceed with whatever else you wanted to accomplish.
Once all the downloading is accomplished, Ant prints
db:
to indicate that
it’s starting to execute the target you requested. A moment later, you
should see the HSQLDB graphical interface, which will look something
like Figure 1-6.
There’s nothing in our database yet, so there’s not much to see beyond
whether the command worked at all. The tree view at the top left of the
window is where the various tables and columns in our database can be
explored. For now, just verify that the top reads jdbc:hsqldb:data/music
.
You can explore the menus a bit if you like, but don’t make any changes to the database. Once you’re done, choose
→ . The window will close, and Ant will report:BUILD SUCCESSFUL Total time: 56 seconds
The amount of time you spend playing may vary, of course. (Recall
that Ant sticks around until the database shuts down because of the
fork
attribute we added to the
java
task.) At this point, if you
look in the data directory, you’ll find that HSQLDB has created some
files to hold the database:
% ls data music.log music.properties music.script
You can even look at the contents of these files. Unlike most database systems, HSQLDB stores its data in a human-readable format by default. The properties file contains some basic settings, and the data itself goes in the script file, in the form of SQL statements. The log file is used to reconstruct a consistent database state if the application crashes or otherwise exits without gracefully closing the database. Right now, all you’ll find in these files are the basic definitions that are entered by default, but as we start creating tables and adding data to them, you can view the file again and see the changes appear in it. This can be a useful debugging feature for basic sanity checks, and is even faster than firing up the graphical interface and running queries.
Note
The fact that you can read HSQLDB’s database files is weird but fun.
What just happened?
Now that we’ve successfully run the first example and set up our
project’s build file, it is probably time to explain how Ant retrieved
all of the necessary dependencies for this project. Let’s re-examine
the artifact:dependencies
element from the
example’s build.xml file (see Example 1-2).
<artifact:dependencies pathId="dependency.classpath"> <dependency groupId="hsqldb" artifactId="hsqldb" version="1.8.0.7"/> <dependency groupId="org.hibernate" artifactId="hibernate" version="3.2.5.ga"> <exclusion groupId="javax.transaction" artifactId="jta"/> </dependency> <dependency groupId="org.hibernate" artifactId="hibernate-tools" version="3.2.0.beta9a"/> <dependency groupId="org.apache.geronimo.specs" artifactId="geronimo-jta_1.1_spec" version="1.1"/> <dependency groupId="log4j" artifactId="log4j" version="1.2.14"/> </artifact:dependencies>
If you’ve never used Maven before, this probably looks
very confusing. Let’s start by defining some terminology.
First there is an artifact. An artifact is a file
that is produced by a project. An artifact can be any
type—a WAR for a web
application, an EAR for an enterprise application, or a
JAR. For our purposes we are depending on
JAR artifacts, and the default type if you don’t
specify it in the dependency element is jar
, conveniently enough.
A specific artifact is identified by four attributes: groupId
, artifactId
, version
, and type
. For example, we are depending on
version 3.2.5.ga
of the hibernate
artifact in group org.hibernate
and the implied type is
jar
. Maven will use these
identifiers to locate the appropriate dependency in the central Maven 2
repository which is hosted at http://repo1.maven.org/maven2/. Using these values, Maven
will attempt to locate the JAR for hibernate using the following
pattern: <
,
where periods in the repositoryUrl
>/<groupId
>/<artifactId
>/<version
>/<artifactId
>-<version
>.<type
>groupId
are
converted to path separators for the URLs that, using
this pattern, would be used to locate the JARs for
the Hibernate and HSQLDB dependencies. See Example 1-3.
http://repo1.maven.org/org/hibernate/hibernate/3.2.5.ga/hibernate-3.2.5.ga.jar http://repo1.maven.org/hsqldb/hsqldb/1.8.0.7/hsqldb-1.8.0.7.jar
In our build.xml file, we are
excluding the JTA dependency from the Hibernate
dependency declaration. This is necessary because the Hibernate library
depends on a nonfree JAR artifact not available on the
public Maven 2 repository. Instead of using the standard Sun-supplied
JTA API JAR,
this project depends on a version of the JTA
API created by the Apache Geronimo project. geronimo-jta_1.1_spec
is a free, open source implementation of the Java Transaction
API. This substitution is accomplished using the
exclusion
element within the
dependency for Hibernate 3.2.5.ga, combined with the explicit dependency
on the Geronimo JTA spec 1.1 later on.
All right, so we have some insight into how the Maven Ant Tasks retrieve the dependencies from the Maven repository, but where do they go once they’ve been downloaded? The Maven Ant Tasks download all dependencies to a local Maven repository. Maven maintains a local repository with a structure that mirrors the remote repository. When it needs to check for an artifact, it checks the local repository first before it requests the artifact from the remote repository. This means that if twenty projects all reference the same version of Hibernate, it is only downloaded from the remote repository once, and all twenty projects will refer to a single copy stored in the local Maven repository. So where is this magical local Maven repository? The easiest way to answer this question is to add a target to our build.xml file. Add the following target to the end of the Ant build.xml from earlier in the chapter, as shown in Example 1-4.
<target name="print-classpath" description="Show the dependency class path"> <property name="class.path" refid="dependency.classpath"/> <echo>${class.path}</echo> </target>
Running this target will produce the following output results:
%
ant print-classpath
Buildfile: build.xml
print-classpath:
[echo] ~\.m2\repository\commons-logging\commons-logging\1.0.4\commons-logging-
1.0.4.jar;\
~\.m2\repository\dom4j\dom4j\1.6.1\dom4j-1.6.1.jar;\
~\.m2\repository\cglib\cglib\2.1_3\cglib-2.1_3.jar;\...
Try running this target. The output will vary depending on which
operating system you are using, but you’ll notice that the dependency
class path refers to your local Maven repository. On a Windows XP
machine this will likely be in C:\Documents and
Settings\Username
\.m2\repository;
on Windows Vista this will likely be in C:\Users\Username
\.m2\repository;
and on Unix and Macintosh this will be the ~/.m2/repository directory.
You will also notice that there are more dependencies listed in
the class path than were declared in the artifact:dependencies
element in build.xml. These extra dependencies are
called transitive dependencies, and they
are dependencies of your explicitly declared dependencies. For example,
Hibernate depends upon CGLib, EHCache, and Commons Collections, among
other things. Although it is outside the scope of this book, I’ll give
you a hint as to how the Maven Ant Tasks figure out the full set of
dependencies for your project. If you explore your local repository
after you’ve built one of the examples, you will notice that next to
every JAR artifact sits a file with the extension
.pom.
Project Object Model files (or POMs) are the foundation of the Maven
build system and repository. Each POM describes an artifact and that
artifact’s dependencies. The Maven Ant Tasks use this metadata to
construct a tree of transitive dependencies. In other words, the Maven
Ant Tasks don’t just take care of downloading Hibernate, they download
everything that Hibernate depends upon.
All you really need to know is that it works.
What’s next?
Thanks to the Maven Ant Tasks, you had far fewer hoops to jump through to find, download, expand, and organize software than did readers of the previous version of this book. You’re in a great position to start working with Hibernate and, as you’ll see in the next chapter, we’ll be moving very quickly. You’ll be able to see Java code written for you! Database schemas created out of thin air (or, at least, out of the same XML mapping table that produced the Java)! Real tables and data appearing in the HSQLDB manager interface! (Or, at least, genuine faux sample data….)
Sound exciting? Well, compared to what you’ve done so far anyway? Then let’s dig in to awakening the power of Hibernate.
Why didn’t it work?
If, on the other hand, you saw no database manager window appear, and instead were greeted by error messages, try to figure out if they’re due to problems in the build file, differences in the way you’ve set up Ant or your project hierarchy, difficulty accessing the Internet to download dependencies from the Maven repository, or something else. Double-check that all the pieces are arranged and installed as shown earlier, and consider downloading the sample code if you are having trouble with a version you typed in yourself.
Get Harnessing Hibernate now with the O’Reilly learning platform.
O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.