By James Elliott, Timothy M. O'Brien, Ryan Fowler
Book Price: $39.99 USD
£24.99 GBP
PDF Price: $31.99
Cover | Table of Contents | Colophon
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)
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.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.
<?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.class.path">
<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.class.path"/>
</path>
<!-- Teach Ant how to use the Hibernate Tools -->
<taskdef name="hibernatetool"
classname="org.hibernate.tool.ant.HibernateToolTask"
classpathref="project.class.path"/>hibernate.dialect=org.hibernate.dialect.HSQLDialect hibernate.connection.driver_class=org.hsqldb.jdbcDriver hibernate.connection.url=jdbc:hsqldb:data/music hibernate.connection.username=sa hibernate.connection.password= hibernate.connection.shutdown=true
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<!-- SQL dialect -->
<property name="dialect">org.hibernate.dialect.HSQLDialect</property>
<!-- Database connection settings -->
<property name="connection.driver_class">org.hsqldb.jdbcDriver</property>
<property name="connection.url">jdbc:hsqldb:data/music</property>
<property name="connection.username">sa</property>
<property name="connection.password"></property>
<property name="connection.shutdown">true</property>
<!-- JDBC connection pool (use the built-in one) -->
<property name="connection.pool_size">1</property>
<!-- Enable Hibernate's automatic session context management -->
<property name="current_session_context_class">thread</property>
<!-- Disable the second-level cache -->
<property
name="cache.provider_class">org.hibernate.cache.NoCacheProvider</property>
<!-- disable batching so HSQLDB will propagate errors correctly. -->
<property name="jdbc.batch_size">0</property>
<!-- Echo all executed SQL to stdout -->
<property name="show_sql">true</property>
<!-- List all the mapping documents we're using -->
<mapping resource="com/oreilly/hh/data/Track.hbm.xml"/>
</session-factory>
</hibernate-configuration><?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<!-- SQL dialect -->
<property name="dialect">org.hibernate.dialect.HSQLDialect</property>
<!-- Database connection settings -->
<property name="connection.driver_class">org.hsqldb.jdbcDriver</property>
<property name="connection.url">jdbc:hsqldb:data/music</property>
<property name="connection.username">sa</property>
<property name="connection.password"></property>
<property name="connection.shutdown">true</property>
<!-- JDBC connection pool (use the built-in one) -->
<property name="connection.pool_size">1</property>
<!-- Enable Hibernate's automatic session context management -->
<property name="current_session_context_class">thread</property>
<!-- Disable the second-level cache -->
<property
name="cache.provider_class">org.hibernate.cache.NoCacheProvider</property>
<!-- disable batching so HSQLDB will propagate errors correctly. -->
<property name="jdbc.batch_size">0</property>
<!-- Echo all executed SQL to stdout -->
<property name="show_sql">true</property>
<!-- List all the mapping documents we're using -->
<mapping resource="com/oreilly/hh/data/Track.hbm.xml"/>
</session-factory>
</hibernate-configuration>package com.oreilly.hh;
import org.hibernate.*;
import org.hibernate.cfg.Configuration;
import com.oreilly.hh.data.*;
import java.sql.Time;
import java.util.Date;
/**
* Create sample data, letting Hibernate persist it for us.
*/
public class CreateTest {
public static void main(String args[]) throws Exception {
// Create a configuration based on the XML file we've put
// in the standard place.
Configuration config = new Configuration();
config.configure();
// Get the session factory we can use for persistence
SessionFactory sessionFactory = config.buildSessionFactory();
// Ask for a session using the JDBC information we've configured
Session session = sessionFactory.openSession();
Transaction tx = null;
try {
// Create some data and persist it
tx = session.beginTransaction();
Track track = new Track("Russian Trance",
"vol2/album610/track02.mp3",
Time.valueOf("00:03:30"), new Date(),
(short)0);
session.save(track);
track = new Track("Video Killed the Radio Star",
"vol2/album611/track12.mp3",
Time.valueOf("00:03:49"), new Date(),
(short)0);
session.save(track);
track = new Track("Gravity's Angel",
"vol2/album175/track03.mp3",
Time.valueOf("00:06:06"), new Date(),
(short)0);
session.save(track);
// We're done; make our changes permanent
tx.commit();
} catch (Exception e) {
if (tx != null) {
// Something went wrong; discard all partial changes
tx.rollback();
}
throw new Exception("Transaction failed", e);
} finally {
// No matter what, close the session
session.close();
}
// Clean up after ourselves
sessionFactory.close();
}
}package com.oreilly.hh;
import org.hibernate.*;
import org.hibernate.cfg.Configuration;
import com.oreilly.hh.data.*;
import java.sql.Time;
import java.util.*;
/**
* Retrieve data as objects
*/
public class QueryTest {
/**
* Retrieve any tracks that fit in the specified amount of time.
*
* @param length the maximum playing time for tracks to be returned.
* @param session the Hibernate session that can retrieve data.
* @return a list of {@link Track}s meeting the length restriction.
*/
public static List tracksNoLongerThan(Time length, Session session) {
Query query = session.createQuery("from Track as track " +
"where track.playTime <= ?");
query.setParameter(0, length, Hibernate.TIME);
return query.list();
}
/**
* Look up and print some tracks when invoked from the command line.
*/
public static void main(String args[]) throws Exception {
// Create a configuration based on the properties file we've put
// in the standard place.
Configuration config = new Configuration();
config.configure();
// Get the session factory we can use for persistence
SessionFactory sessionFactory = config.buildSessionFactory();
// Ask for a session using the JDBC information we've configured
Session session = sessionFactory.openSession();
try {
// Print the tracks that will fit in five minutes
List tracks = tracksNoLongerThan(Time.valueOf("00:05:00"),
session);
for (ListIterator iter = tracks.listIterator() ;
iter.hasNext() ; ) {
Track aTrack = (Track)iter.next();
System.out.println("Track: \"" + aTrack.getTitle() +
"\", " + aTrack.getPlayTime());
}
} finally {
// No matter what, close the session
session.close();
}
// Clean up after ourselves
sessionFactory.close();
}
}package com.oreilly.hh; import org.hibernate.*; import org.hibernate.cfg.Configuration; import com.oreilly.hh.data.*; import java.sql.Time; import java.util.*; /** * Create more sample data, letting Hibernate persist it for us. */ public class CreateTest { /** * Look up an artist record given a name. * @param name the name of the artist desired. * @param create controls whether a new record should be created if * the specified artist is not yet in the database. * @param session the Hibernate session that can retrieve data * @return the artist with the specified name, or <code>null</code> if no * such artist exists and <code>create</code> is <code>false</code>. * @throws HibernateException if there is a problem. */ public static Artist getArtist(String name, boolean create, Session session) { Query query = session.getNamedQuery("com.oreilly.hh.artistByName"); query.setString("name", name); Artist found = (Artist)query.uniqueResult(); if (found == null && create) { found = new Artist(name, new HashSet<Track>()); session.save(found); } return found; } /** * Utility method to associate an artist with a track */ private static void addTrackArtist(Track track, Artist artist) { track.getArtists().add(artist); }
package com.oreilly.hh;
import org.hibernate.*;
import org.hibernate.cfg.Configuration;
import com.oreilly.hh.data.*;
import java.sql.Time;
import java.util.*;
/**
* Retrieve data as objects
*/
public class QueryTest {
/**
* Retrieve any tracks that fit in the specified amount of time.
*
* @param length the maximum playing time for tracks to be returned.
* @param session the Hibernate session that can retrieve data.
* @return a list of {@link Track}s meeting the length restriction.
*/
public static List tracksNoLongerThan(Time length, Session session) {
Query query = session.getNamedQuery(
"com.oreilly.hh.tracksNoLongerThan");
query.setTime("length", length);
return query.list();
}
/**
* Build a parenthetical, comma-separated list of artist names.
* @param artists the artists whose names are to be displayed.
* @return the formatted list, or an empty string if the set was empty.
*/
public static String listArtistNames(Set<Artist> artists) {
StringBuilder result = new StringBuilder();
for (Artist artist : artists) {
result.append((result.length() == 0) ? "(" : ", ");
result.append(artist.getName());
}
if (result.length() > 0) {
result.append(") ");
}
return result.toString();
}package com.oreilly.hh;
import org.hibernate.*;
import org.hibernate.cfg.Configuration;
import com.oreilly.hh.data.*;
import java.sql.Time;
import java.util.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
/**
* Provide a user interface to enter artist names and see their tracks.
*/
public class QueryTest2 extends JPanel {
JList list; // Will contain tracks associated with current artist
DefaultListModel model; // Lets us manipulate the list contents
/**
* Build the panel containing UI elements
*/
public QueryTest2() {
setLayout(new BorderLayout());
model = new DefaultListModel();
list = new JList(model);
add(new JScrollPane(list), BorderLayout.SOUTH);
final JTextField artistField = new JTextField(28);
artistField.addKeyListener(new KeyAdapter() {
public void keyTyped(KeyEvent e) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
updateTracks(artistField.getText());
}
});
}
});
add(artistField, BorderLayout.EAST);
add(new JLabel("Artist: "), BorderLayout.WEST);
}
/**
* Update the list to contain the tracks associated with an artist
*/
private void updateTracks(String name) {
model.removeAllElements(); // Clear out previous tracks
if (name.length() < 1) return; // Nothing to do
try {
// Ask for a session using the JDBC information we've configured
Session session = sessionFactory.openSession();
try {
Artist artist = CreateTest.getArtist(name, false, session);
if (artist == null) { // Unknown artist
model.addElement("Artist not found");
return;
}
// List the tracks associated with the artist
for (Track aTrack : artist.getTracks()) {
model.addElement("Track: \"" + aTrack.getTitle() +
"\", " + aTrack.getPlayTime());
}
} finally {
// No matter what, close the session
session.close();
}
} catch (Exception e) {
System.err.println("Problem updating tracks:" + e);
e.printStackTrace();
}
}
private static SessionFactory sessionFactory; // Used to talk to Hibernate
/**
* Set up Hibernate, then build and display the user interface.
*/
public static void main(String args[]) throws Exception {
// Load configuration properties, read mappings for persistent classes
Configuration config = new Configuration();
config.configure();
// Get the session factory we can use for persistence
sessionFactory = config.buildSessionFactory();
// Set up the UI
JFrame frame = new JFrame("Artist Track Lookup");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setContentPane(new QueryTest2());
frame.setSize(400, 180);
frame.setVisible(true);
}
}<set name="comments" table="TRACK_COMMENTS"> <key column="TRACK_ID"/> <element column="COMMENT" type="string"/> </set>
[hibernatetool] create table TRACK_COMMENTS (TRACK_ID integer not null, COMMENT varchar(255)); ... [hibernatetool] 16:16:55,876 DEBUG SchemaExport:303 - alter table TRACK_COMMENTS add constraint FK105B26882DCBFAB5 foreign key (TRACK_ID) references TRACK;