O'Reilly logo

Harnessing Hibernate by James Elliott, Ryan Fowler, Timothy M. O'Brien

Stay ahead with the world's most comprehensive technology and business learning platform.

With Safari, you learn the way you learn best. Get unlimited access to videos, live online training, learning paths, books, tutorials, and more.

Start Free Trial

No credit card required

Retrieving Collections

You might expect that getting the collection information back out of the database is similarly easy. You’d be right! Let’s enhance our QueryTest class so it shows us the artists associated with the tracks it displays. Example 4-10 shows the appropriate changes and additions in bold. Little new code is needed.

Example 4-10. QueryTest.java enhanced to display artists associated with tracks

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(
        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) { 1
      StringBuilder result = new StringBuilder();
      for (Artist artist : artists) {
            result.append((result.length() == 0) ? "(" : ", ");                 
        if (result.length() > 0) {                                              
            result.append(") ");                                                
        return result.toString();                                               

     * 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 XML file we've put
        // in the standard place.
        Configuration config = new Configuration();

        // 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 seven minutes
            List tracks = tracksNoLongerThan(Time.valueOf("00:07:00"), 2
            for (ListIterator iter = tracks.listIterator() ;
                 iter.hasNext() ; ) {
                Track aTrack = (Track)iter.next();
                System.out.println("Track: \"" + aTrack.getTitle() + "\" " +    
                                   listArtistNames(aTrack.getArtists()) + 3
        } finally {
            // No matter what, close the session

        // Clean up after ourselves

The first thing we add is a little utility method to format the set of artist names nicely, as a comma-delimited list inside parentheses, with proper spacing, or as nothing at all if the set of artists is empty.


Since all the interesting new multiartist tracks are longer than five minutes, we increase the cutoff in our query to seven minutes so we can see some results.


Finally, we call listArtistNames() at the proper position in the println() statement describing the tracks found.

At this point, it’s time to get rid of Hibernate’s query debugging output, because it will prevent us from seeing what we want to see. Edit hibernate.cfg.xml in the src directory, and change the show_sql property value to false:

    <!-- Echo all executed SQL to stdout -->
    <property name="show_sql">false</property>

With this done, Example 4-11 shows the new output from ant qtest.

Example 4-11. QueryTest output with artist information

% ant qtest
Buildfile: build.xml


    [javac] Compiling 1 source file to /Users/jim/svn/oreilly/hib_dev_2e/current

     [java] Track: "Russian Trance" (PPK) 00:03:30
     [java] Track: "Video Killed the Radio Star" (The Buggles) 00:03:49
     [java] Track: "Gravity's Angel" (Laurie Anderson) 00:06:06
     [java] Track: "Adagio for Strings (Ferry Corsten Remix)" (Ferry Corsten, Wi
lliam Orbit, Samuel Barber) 00:06:35
     [java] Track: "Test Tone 1" 00:00:10

Total time: 2 seconds

You’ll notice two things. First, you'll see that this is much easier to interpret than the columns of numbers in Figure 4-2, and second, it worked! Even in the “tricky” case of the test tone track without any artist mappings, Hibernate takes the friendly approach of creating an empty artists Set, sparing us from peppering our code with the null checks we’d otherwise need to avoid crashing with NullPointerExceptions.


But wait, there’s more! No additional code needed….

With Safari, you learn the way you learn best. Get unlimited access to videos, live online training, learning paths, books, interactive tutorials, and more.

Start Free Trial

No credit card required