2006 Ken Kousen. All rights reserved by Capstone Courseware, LLC. ii. 118.
Java Persistence with Hibernate. Version 3.2.1. Information in this document is ...
Java Persistence with Hibernate
Ken Kousen
Version 3.2.1
118. Java Persistence with Hibernate Version 3.2.1
Information in this document is subject to change without notice. Companies, names and data used in examples herein are fictitious unless otherwise noted. No part of this document may be reproduced or transmitted in any form or by any means, electronic or mechanical, for any purpose, without the express written permission of the author. A publication of Capstone Courseware, LLC. 877-227-2477 www.capstonecourseware.com © 2006 Ken Kousen. All rights reserved. Published in the United States. This book is printed on 100% recycled paper.
© 2006 Ken Kousen. All rights reserved by Capstone Courseware, LLC.
ii
Course Overview Chapter 1 Chapter 2 Chapter 3 Chapter 4 Chapter 5 Chapter 6
Introduction to Hibernate Configuring Hibernate Hibernate Persistence Object/Relational Mapping The Criteria Query API The Hibernate Query Language
Appendix A
Learning Resources
© 2006 Ken Kousen. All rights reserved by Capstone Courseware, LLC.
iii
Prerequisites • Students will need a solid background in Java programming to use Hibernate. • Familiarity with relational database concepts is assumed. • SQL knowledge is helpful as well.
© 2006 Ken Kousen. All rights reserved by Capstone Courseware, LLC.
iv
Labs • The course relies on hands-on experience in various topics and techniques. • All lab code is 100% Pure Java, written to build and run on the Java Standard Edition JDK, version 5.0. • Labs for this course have been installed to the hard drive on each student machine. • Lab files will be usually be found under: − c:/Capstone for Windows systems − $HOME/Capstone for Linux systems
• This is Capstone Courseware’s root directory, shared by this course along with others from the Capstone curriculum. • In some cases your instructor may have chosen a different root location.
© 2006 Ken Kousen. All rights reserved by Capstone Courseware, LLC.
v
Directory Structure for the Course • The course will install to a combination of this shared course root and its own module root directory c:/Capstone/Hibernate. − Under this root, the Examples directory holds code examples, including all the starting, intermediate and answer versions of all the labs. − The Demos directory is home to files that relate to in-class demonstrations. Demonstrations creating files from scratch should also use this directory. − The Labs directory holds one subdirectory for each lab in the course, named for the lab number. This is where you will do the bulk of your lab work, with some reference to code in the Examples directory. − The Ant directory holds common build files for web projects.
• Throughout the rest of this student guide, we will refer to directories by relative paths from the module root, as in: − Examples/JDBC/Step1 − Demos/UsersRoles − Labs/Lab5
© 2006 Ken Kousen. All rights reserved by Capstone Courseware, LLC.
vi
Table of Contents Chapter 1. Introduction to Hibernate..................................................... 1 Introducing Hibernate............................................................................................................3 The Object/Relational Mapping Problem ............................................................................4 The “Impedance Mismatch” ..................................................................................................5 JDBC .........................................................................................................................................6 The Users-Roles Schema ........................................................................................................9 Tools and Environment Setup............................................................................................ 12 Creating the Database.......................................................................................................... 13 The Role Class....................................................................................................................... 14 Example: A JDBC Query ..................................................................................................... 16 The Hibernate Alternative .................................................................................................. 20 Example: Using Hibernate .................................................................................................. 22 XML Tools............................................................................................................................. 30 Lab1: Mapping the USERS Table ....................................................................................... 31
Chapter 2. Configuring Hibernate ........................................................ 35 Hibernate Distributions....................................................................................................... 37 The Hibernate Distribution ................................................................................................ 39 Required Libraries................................................................................................................ 41 Configuration Files .............................................................................................................. 42 hibernate.properties ............................................................................................................. 43 hibernate.cfg.xml.................................................................................................................. 44 XML Configuration Model ................................................................................................. 45 Programmatic Configuration ............................................................................................. 46 Lab2: Hibernate Configuration .......................................................................................... 49
© 2006 Ken Kousen. All rights reserved by Capstone Courseware, LLC.
vii
Chapter 3. Hibernate Persistence ......................................................... 55 The Hibernate Architecture................................................................................................ 57 Interface Model..................................................................................................................... 58 SessionFactory ...................................................................................................................... 59 Example: A Hibernate Utility Class ................................................................................... 60 SessionFactory Methods...................................................................................................... 62 Hibernate Sessions ............................................................................................................... 63 Object States.......................................................................................................................... 64 State Transitions................................................................................................................... 65 Session Methods ................................................................................................................... 66 Object States, Again ............................................................................................................. 69 Transactions.......................................................................................................................... 70 Session-Per-Operation......................................................................................................... 71 Session-Per-Request............................................................................................................. 72 The Data Access Object Pattern ......................................................................................... 74 Demo: Building A UserDAO Class.................................................................................... 75 Lab3: Creating a RoleDAO Class ....................................................................................... 81
Chapter 4. Object/Relational Mapping................................................. 87 Object-Oriented Design ...................................................................................................... 89 Relational Mapping.............................................................................................................. 91 Demo: Mapping Users to Roles.......................................................................................... 93 Bidirectional Association .................................................................................................... 98 Lab4A: Mapping Roles to Users ....................................................................................... 100 O/R Mapping Techniques................................................................................................. 101 The Mapping Document ................................................................................................... 102 The Mapping XML Model ................................................................................................ 103 Primary Keys and Identity ................................................................................................ 104 Generating Identifiers........................................................................................................ 105 The element.................................................................................................... 106 Other Mapping Elements .................................................................................................. 107 Earthlings Schema.............................................................................................................. 108 Earthlings Relationships.................................................................................................... 109 Earthlings UML .................................................................................................................. 110 Components........................................................................................................................ 111 Example: Employee Mapping ........................................................................................... 112 Lab4B: Basic Mapping of Earthlings................................................................................ 119 Mapping Associations ....................................................................................................... 120 The Mapping XML Model for Associations ................................................................... 122 Unidirectional Many-to-One............................................................................................ 123 Demo: Mapping Departments to Locations ................................................................... 124 © 2006 Ken Kousen. All rights reserved by Capstone Courseware, LLC.
viii
Eager Fetching .................................................................................................................... 126 Bidirectional One-To-Many ............................................................................................. 127 Demo: Adding Employees to Departments .................................................................... 128 Bidirectional One-To-One................................................................................................ 132 Example: Managing Departments.................................................................................... 133 Lab4C: Mapping Employees to Jobs ................................................................................ 135 Mapping Inheritance ......................................................................................................... 136 Inheritance and Databases ................................................................................................ 138 Single-Table Inheritance ................................................................................................... 139 Mapping Single-Table Inheritance .................................................................................. 140 Example: Employee Inheritance....................................................................................... 141 Table-Per-Subclass ............................................................................................................. 146 Table-Per-Subclass Mapping ............................................................................................ 147 Table-Per-Concrete-Class ................................................................................................. 148
Chapter 5. The Criteria Query API .......................................................157 Criteria Queries .................................................................................................................. 159 The Criteria Interface ........................................................................................................ 160 The Criteria API ................................................................................................................. 161 The Restriction Class Utility ............................................................................................. 162 Other Restrictions .............................................................................................................. 165 Example: Conjunction and Disjunction.......................................................................... 166 Windowing Results ............................................................................................................ 168 Example: Printing Employees in Windows .................................................................... 169 Sorting Query Results ........................................................................................................ 170 Example: Associations ....................................................................................................... 171 Projections and Aggregates............................................................................................... 172 The Projections Class Utility ............................................................................................ 173 The ProjectionList Class.................................................................................................... 174 Example: Multiple Projections ......................................................................................... 175 Example: Property Projections ......................................................................................... 176 Example: Group By ............................................................................................................ 177 Query By Example.............................................................................................................. 178 Example: Employees in Massachusetts............................................................................ 179 Example: QBE and Associations ...................................................................................... 180 Lab5: Criteria Queries........................................................................................................ 181
© 2006 Ken Kousen. All rights reserved by Capstone Courseware, LLC.
ix
Chapter 6. The Hibernate Query Language .......................................185 The Hibernate Query Language ....................................................................................... 187 Fundamentals ..................................................................................................................... 188 Example: Executing an HQL Query................................................................................. 189 HQL Queries....................................................................................................................... 191 Polymorphism .................................................................................................................... 192 Example: The Select Clause............................................................................................... 193 Example: The Where Clause............................................................................................. 194 Named Parameters............................................................................................................. 195 Entity Parameters ............................................................................................................... 196 Example: Entity Parameters.............................................................................................. 197 Example: Ordering ............................................................................................................. 198 Joining on Associations ..................................................................................................... 199 Example: Joining on Associations.................................................................................... 200 Example: Traversing Associations ................................................................................... 201 Aggregate Methods ............................................................................................................ 204 Updates and Deletes........................................................................................................... 205 Lab6: Hibernate Queries.................................................................................................... 206 Named Queries................................................................................................................... 207 Example: A Named Query ................................................................................................ 208 Using Native SQL............................................................................................................... 209 Example: Native SQL Queries .......................................................................................... 210
Appendix A. Learning Resources ........................................................213
© 2006 Ken Kousen. All rights reserved by Capstone Courseware, LLC.
x
CHAPTER 1
INTRODUCTION TO HIBERNATE
Java Persistence with Hibernate
Chapter 1
OBJECTIVES After completing “Introduction to Hibernate,” you will be able to: • Understand Hibernate as an open source project. • Relate Hibernate to the standard JDBC persistence model. • Discuss issues related to persistence of “plain old java objects” (“POJOs”). • Identify the goals of Object/Relational Mapping tools. • Demonstrate a "Hello, World" example.
© 2006 Ken Kousen. All rights reserved by Capstone Courseware, LLC.
2
Java Persistence with Hibernate
Chapter 1
Introducing Hibernate • Hibernate is an open source project whose purpose is to make it easy to integrate relational data into Java programs. • This is done through the use of XML mapping files, which associate Java classes with database tables. • Hibernate provides basic mapping capabilities. It also includes several other object/relational mapping (ORM) capabilities, including: − An enhanced, object-based SQL variant for retrieving data, known as Hibernate Query Language (HQL). − Automated processes to synchronize objects with their database equivalents. − Built-in database connection pooling, including three opensource variants. − Transactional capabilities that can work both stand-alone or with existing Java Transaction API (JTA) implementations.
• The goal of Hibernate is to allow object-oriented developers to incorporate persistence into their programs with a minimum of effort.
© 2006 Ken Kousen. All rights reserved by Capstone Courseware, LLC.
3
Java Persistence with Hibernate
Chapter 1
The Object/Relational Mapping Problem • In general, enterprise-level programs are built using objectoriented programming languages, like Java, C#, VB.NET, Ruby, and so on. • Object-oriented programming techniques have several advantages over procedural methodologies, all based in some way on maintainability and extensibility. − OO programs tend to scale better, due to the absence of global variables and the use of clean interfaces between modules. − Maintenance is enhanced partly by modularity and partly by hiding the details of internal data structures inside classes. − Extending existing systems is relatively easy both by composition and by inheritance.
• The vast majority of persistence implementations use relational databases, like IBM DB2, Microsoft SQL Server, Oracle’s various offerings, and even open-source alternatives like Apache Derby, Hypersonic SQL, and MySQL. • Relational database management systems (RDBMS) have their own set of advantages. − Relational theory is an established body of mathematical body of knowledge that assists in effective design and implementation, − RDBMS have been optimized for speed and data integrity. − Scaling experience has grown to the point that terabyte-sized systems are no longer uncommon.
© 2006 Ken Kousen. All rights reserved by Capstone Courseware, LLC.
4
Java Persistence with Hibernate
Chapter 1
The “Impedance Mismatch” • In most systems with a significant amount of business logic and data in relational databases, there is an impedance mismatch. − The business logic is normally written in an object-oriented (OO) language, because OO systems are generally easier to revise and extend. The primary design criterion for them is maintainability. − Database systems are almost always relational. The primary design criterion for them is speed and data integrity.
• Both sides do their jobs quite well, but differ fundamentally at the boundary. • Good object-oriented design practices suggest that where there is a boundary, it is prudent to add a layer. − Rather than access database structures throughout an OO program, build a set of classes that map the tabular data to objects and back again. − A transformation layer isolates changes into a relatively small number of classes, so that when either the classes or the tables change, only a small portion of the code needs to be revised. − Another benefit of a layer is that it provides a single area where SQL statements can be intermixed with the OO language. − Even if the database structures do not change fundamentally, the SQL code that accesses them is often revised and refined. − The design patterns literature refers to this layer as the Data Access Object design pattern, which is discussed later in this course. © 2006 Ken Kousen. All rights reserved by Capstone Courseware, LLC.
5
Java Persistence with Hibernate
Chapter 1
JDBC • Every OO program that accesses a database performs its own object/relational mapping. • The simplest ORM tool in Java is provided by the JDBC API, which is part of the standard edition libraries. − The classes and interfaces in the java.sql and javax.sql packages allow Java programs to interact with database data. − JDBC uses drivers to isolate vendor-specific features and adapt any RDBMS to the JDBC API: Java Application
JDBC Driver Manager Type 1
Type 2
JDBC/ODBC Bridge Driver
Partial or Full Java Driver
ODBC Driver
DB Client Library
Type 3 Pure-Java Driver
Type 4 Pure-Java Driver
Local host Network DB MIddleware
RDBMS
RDBMS
© 2006 Ken Kousen. All rights reserved by Capstone Courseware, LLC.
RDBMS
RDBMS
6
Java Persistence with Hibernate
Chapter 1
JDBC • The JDBC library forms a thin layer between the OO classes and the database tables. • The following UML diagram summarizes the JDBC driver interfaces most useful to application code:
© 2006 Ken Kousen. All rights reserved by Capstone Courseware, LLC.
7
Java Persistence with Hibernate
Chapter 1
JDBC • Java classes manage the connection to the database as well as passing SQL statements to it. − The Connection interface represents a DB connection, a scarce resource normally managed by a connection pool. − The various Statement interfaces pass SQL commands to the database. − The ResultSet interface provides access to the virtual table resulting from a SELECT statement. − Characteristics of the ResultSet, like number of columns and data types, can be found from the ResultSetMetaData interface.
• Any mapping between database tables and the middleware classes is provided by Java code. − Values are extracted from the ResultSet and used to populate instances of Java classes.
© 2006 Ken Kousen. All rights reserved by Capstone Courseware, LLC.
8
Java Persistence with Hibernate
Chapter 1
The Users-Roles Schema • As a simple example, consider a typical authentication system for a web site. − The site uses a simple username/password combination to authenticate users.
• Security is applied in terms of standard roles. − Users are assigned to roles. − Roles determine which pages a user may access.
• A typical database schema modeling users and roles is given below. • The schema consists of three tables: − ROLES, which has an ID column of type int and a role_name column of type varchar. − USERS, which has an ID column of type int, a user_name column of type varchar and a user_pass column of type varchar. − USERS_ROLES, a linking table with two columns, user_id and role_id, which are foreign keys to the other two tables.
© 2006 Ken Kousen. All rights reserved by Capstone Courseware, LLC.
9
Java Persistence with Hibernate
Chapter 1
The Users-Roles Schema • An entity/relationship diagram for this model is given below.
• Contrast this with the likely object-oriented model of the same information:
© 2006 Ken Kousen. All rights reserved by Capstone Courseware, LLC.
10
Java Persistence with Hibernate
Chapter 1
The Users-Roles Schema • A SQL DDL script to build the tables is as follows: CREATE TABLE USERS ( ID INT not null auto_increment, user_name VARCHAR(50), user_pass VARCHAR(50), primary key(id) ); CREATE TABLE ROLES ( ID INT not null auto_increment, role_name VARCHAR(50), primary key(id) ); CREATE TABLE USERS_ROLES ( USER_ID INT, ROLE_ID INT, constraint fk_user_id foreign key (user_id) references users(id), constraint fk_role_id foreign key (role_id) references roles(id) );
• The USERS and ROLES tables are very simple, consisting only of a primary key column and strings. • The USERS_ROLES table is a link table, used to represent a many-to-many relationship between USERS and ROLES. • In this example, only the ROLES table will be examined. Later, the many-to-many relationship will be modeled. • The createdb.sql script in the actual code also inserts data into the three tables.
© 2006 Ken Kousen. All rights reserved by Capstone Courseware, LLC.
11
Java Persistence with Hibernate
Chapter 1
Tools and Environment Setup • For exercises in this course, we’ll rely on four primary tools: − The Java 5.0 SDK − The Ant build utility, version 1.6 − Hibernate, of course − The MySQL RDBMS, version 5.0
• These have all been installed on your machine. − Ant, Hibernate, and MySQL are found bundled with the lab software, in subdirectories of c:/Capstone/Tools.
• To support the prepared Ant build files, you will need to assure two things about your build environment: − The executable path must include the Java SDK’s bin directory and also Ant’s own bin directory. A typical setting is path=c:\Windows;c:\Windows\System32; c:\j2sesdk5.0\bin;c:\Capstone\Tools\Ant1.6\bin
− An environment variable CC_MODULE must be defined to the root of the lab tree; for default installations of the labs this is CC_MODULE=c:\Capstone\Hibernate
© 2006 Ken Kousen. All rights reserved by Capstone Courseware, LLC.
12
Java Persistence with Hibernate
Chapter 1
Creating the Database • Start the MySQL database server: − Open a command console and set the working directory to c:\Capstone\Tools\MySQL5.0\bin
− From there, simply type mysqld
− You will see no output, the process just appears to hang. It is now listening for connections on a local network port.
• To shut down the server – though you can potentially leave it running for the whole class – use the prepared script: shutdown
− You’ll need a separate console for this. After it runs you’ll see the mysqld process quietly terminate and return you to a command prompt.
• To create the UsersRoles schema, open a console in Examples/UsersRoles/JDBC, and run createdb, which launches the mysql terminal and feed it commands from the prepared SQL script createdb.sql shown earlier. createdb
• Particulars are encoded in the Ant build files. − Database URLs are of the form jdbc:mysql://localhost/db_name. − We use a default installation of MySQL in which the user root has no password.
© 2006 Ken Kousen. All rights reserved by Capstone Courseware, LLC.
13
Java Persistence with Hibernate
Chapter 1
The Role Class • In Java, connected result sets are not passed from the database layer to other application layers. Instead, each row is converted to an object and the collection of objects is returned. • For this case, to demonstrate querying the database for all the roles in the database, we need a Role class. package cc.db.beans.Role; public class Role implements java.io.Serializable { private Integer id; private String name; public Role() {} public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String roleName) { this.name = roleName; } }
© 2006 Ken Kousen. All rights reserved by Capstone Courseware, LLC.
14
Java Persistence with Hibernate
Chapter 1
The Role Class • The Role class uses an id attribute of type java.lang.Integer rather than the int primitive. − This is not required, but has advantages later when dealing with Hibernate.
• The class implements the java.io.Serializable interface, which is also not required but typical. It implies that instances of the Role class will be passed by value from one layer to another. • Hibernate will use the “get” and “set” methods to populate instances of this class for each row in the database. − Without Hibernate, this is normally done in code, as shown in the sample below.
• The toString method has been overridden to make it easy to print objects of this class.
© 2006 Ken Kousen. All rights reserved by Capstone Courseware, LLC.
15
Java Persistence with Hibernate
A JDBC Query
Chapter 1
EXAMPLE
• This example will show how to access all the rows in the ROLES table, convert them to instances of the Role class, and print them. The code can be found in Examples/UsersRoles/JDBC. • Connecting to the database using JDBC involves 1. Loading the appropriate database driver. 2. Opening a connection using a JDBC URL. 3. Creating a java.sql.Statement, or its subinterfaces PreparedStatement or CallableStatement. 4. Using the Statement to pass SQL to the database. 5. Processing the returned java.sql.ResultSet (if the SQL was a query) or checking the update count (if the SQL was an INSERT, UPDATE, or DELETE). 6. Closing everything.
• Nearly everything in JDBC can throw a SQLException, so the code must be wrapped in all the needed try/catch blocks.
© 2006 Ken Kousen. All rights reserved by Capstone Courseware, LLC.
16
Java Persistence with Hibernate
A JDBC Query
Chapter 1
EXAMPLE
import java.sql.*; import cc.db.beans.Role; public class PrintRolesJDBC { public static void main(String[] args) { Connection conn = null; Statement stmt = null; try { Class.forName("com.mysql.jdbc.Driver"); conn = DriverManager.getConnection( "jdbc:mysql://localhost/authdb", "admin", "password"); stmt = conn.createStatement(); ResultSet rs = stmt.executeQuery( "SELECT * FROM ROLES"); while (rs.next()) { Role role = new Role(); role.setId(rs.getInt("id")); role.setName(rs.getString("role_name")); System.out.println(role); } rs.close(); } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (SQLException e) { e.printStackTrace(); } finally { try { if (stmt != null) stmt.close(); if (conn != null) conn.close(); } catch (SQLException e) { e.printStackTrace(); } } }
© 2006 Ken Kousen. All rights reserved by Capstone Courseware, LLC.
17
Java Persistence with Hibernate
A JDBC Query
Chapter 1
EXAMPLE
• Test the application now with the following commands: ant run cc.db.jdbc.PrintRolesJDBC (1,user) (2,admin)
• Immediate issues related to this code: − The name of the driver class, the JDBC URL, the username and the password are all hard-wired into the code. − A try/catch block is required for loading the driver, in case it isn’t found in the classpath of the application.
• By moving to a DataSource, the driver, URL, username and password can all be removed, but this requires an application server or some other mechanism that supports JNDI. • Alternative, light-weight approaches exist (such as the Spring framework), but they, too, require properties files, datasources, and additional configuration. • In the while loop that processes the ResultSet, − The value of each column in the ResultSet is extracted using the proper “get” method (here, getInt and getString) − The data for each row is then assigned to a property of the Role class using the corresponding “set” methods, setId and setName − Printing the object is done by putting the Role reference inside System.out.println. This invokes the toString method on the Role object, so this method should be overridden appropriately
© 2006 Ken Kousen. All rights reserved by Capstone Courseware, LLC.
18
Java Persistence with Hibernate
A JDBC Query
Chapter 1
EXAMPLE
• Since database connections are considered scarce resources, all connected elements must be closed as soon as possible. − ResultSet is closed in the try block here. − Statement and Connection are closed in the finally block to guarantee that they are closed whether an exception is thrown or not. − The calls to close in the finally block must be guarded by an if statement to ensure that a NullPointerException isn’t thrown accidentally. − Since even the close method of both Statement and Connection can throw a SQLException, they too require try/catch blocks.
• Exception handling considerably increases the amount of code required. − Only the stack trace of any exceptions is being printed here. − In a real system, logging would likely be done and the SQL exceptions might be rethrown as application exceptions. − For debugging purposes it would probably be better to close the Statement and Connection in separate try/catch blocks.
• Note also that object/relational mapping is being done manually here by extracting data from the ROLES table and assigning it to properties of the Role class.
© 2006 Ken Kousen. All rights reserved by Capstone Courseware, LLC.
19
Java Persistence with Hibernate
Chapter 1
The Hibernate Alternative • Hibernate uses an API that encapsulates the details of the database connection, as well as the mapping between Java classes and database tables. • The database connection details are normally configured in an external file. − A hibernate.properties file can be used, which is a simple text file containing keys and values. − An XML alternative is available whose default name is hibernate.cfg.xml. The XML file covers the same properties, but allows some additional configuration to be done. This is the most common approach. − The connection can also be configured purely in code, but this is rare. − Each option is discussed in the next chapter.
© 2006 Ken Kousen. All rights reserved by Capstone Courseware, LLC.
20
Java Persistence with Hibernate
Chapter 1
The Hibernate Alternative • The mappings between database tables and Java classes are defined using XML configuration files. − Each Java class requires its own customizable mapping file. The correspondence between Java classes and database tables is not necessarily one-to-one, however. − Multiple classes can be mapped to a single table. This is typically done where a Java class model would naturally separate two concepts, like Employee and Address, but the relational model would store all the information together to minimize the number of joins required. − All sorts of exotic relationships can be modeled. − Cardinality relationships (one-to-one, one-to-many, many-tomany) can be defined. − Navigability can be established.
• Transactions are a fundamental part of every Hibernate program. − Even in a read-only program like the example below, access to the database is done between a beginTransaction call and a commit statement.
© 2006 Ken Kousen. All rights reserved by Capstone Courseware, LLC.
21
Java Persistence with Hibernate
Using Hibernate
Chapter 1
EXAMPLE
• The code in Examples/UsersRoles/Hibernate illustrates how Hibernate can be used to solve the same problem. • Hibernate reduces the required Java coding considerably, but the trade-off is the number of XML files that must be defined. − An overall Hibernate configuration file is created for each database. − Individual mapping files need to be defined for each class.
• The Hibernate configuration file consists of a series of keys and values, which either form a properties file or are specified in XML. Some defined values include: − Dialect (specified for each database vendor) − URL, driver class, username, password − Other helpful properties, like show_sql − Location of mapping files for individual classes
© 2006 Ken Kousen. All rights reserved by Capstone Courseware, LLC.
22
Java Persistence with Hibernate
Using Hibernate
Chapter 1
EXAMPLE
• Here is the XML configuration file, src/hibernate.cfg.xml: org.hibernate.dialect.MySQLDialect com.mysql.jdbc.Driver jdbc:mysql://localhost/authdb admin password org.hibernate.cache.HashtableCacheProvider true
© 2006 Ken Kousen. All rights reserved by Capstone Courseware, LLC.
23
Java Persistence with Hibernate
Using Hibernate
Chapter 1
EXAMPLE
• The above file looks more complicated than it is. The Hibernate configuration consists of a series of properties, each of which is identified as an attribute of the element. • This configuration file holds all the connection details, such as username, password, database driver, and URL. It also specifies the Hibernate dialect, which is used to identify the particular flavor of SQL needed for this vendor. − A list of supported dialects is contained in the hibernate.properties file, which is discussed in the next chapter.
• The mapping file also allows other interesting properties to be specified, such as show_sql. This property tells Hibernate to output the generated SQL code to the console. • Finally, the file includes a tag which specifies the location of the specific XML mapping file for the Role class. • The XML file requires a DOCTYPE declaration which is as follows:
• The DOCTYPE declares − The root element of the XML file, − Information about the owner of the language and its version − The URL where the DTD could be downloaded, if necessary © 2006 Ken Kousen. All rights reserved by Capstone Courseware, LLC.
24
Java Persistence with Hibernate
Using Hibernate
Chapter 1
EXAMPLE
• The mapping file for the Role class specifies: − The Java class being mapped, as well as its package − The database table associated with this class − The primary key column for the table − Specific property mappings (the String data type here is inferred)
• The mapping file for the Role class is as follows:
© 2006 Ken Kousen. All rights reserved by Capstone Courseware, LLC.
25
Java Persistence with Hibernate
Using Hibernate
Chapter 1
EXAMPLE
• The mapping file has a different DOCTYPE declaration, meaning that the mapping files are from a different XML vocabulary than the configuration file. − Its presence is required by Hibernate.
• The mapping file tells Hibernate what it needs to know in order to manage persistence for the role type: − There is only one class, cc.db.beans.Role. − There is only one table, ROLES. − The ROLES table is part of the authdb database, here identified by the catalog attribute. − The element states that the primary key value is generated by the database when rows are inserted. The various options for this are discussed in a later chapter. − The single element maps the name attribute of the Role class to the role_name column of the ROLES table. Since no data type is identified, Hibernate assumes that the same data type is used for both the class and the table. By reflection, this is identified as a java.lang.String.
© 2006 Ken Kousen. All rights reserved by Capstone Courseware, LLC.
26
Java Persistence with Hibernate
Using Hibernate
Chapter 1
EXAMPLE
• With these files in the application classpath, the Java code becomes: import java.util.* import org.hibernate.*; import org.hibernate.cfg.Configuration; import cc.db.beans.Role; public class PrintRoles { @SuppressWarnings("unchecked") public static void main(String[] args) { SessionFactory factory = new Configuration() .configure().buildSessionFactory(); Session session = factory.openSession(); Transaction tx = session.beginTransaction(); Criteria crit = session.createCriteria(Role.class); List roles = crit.list(); tx.commit(); for (Role r : roles) { System.out.println(r); } session.close(); factory.close(); } }
© 2006 Ken Kousen. All rights reserved by Capstone Courseware, LLC.
27
Java Persistence with Hibernate
Using Hibernate
Chapter 1
EXAMPLE
• The application uses a Hibernate SessionFactory class to represent all the connection information. − The SessionFactory reads the configuration file, generates any required connections, and pools them. − Normally the SessionFactory instance is created only once in a given application and cached.
• The Session class represents a single interaction with the database (to be discussed in depth later). • The Transaction class represents a database transaction. • The Criteria interface is used as a simplified API for retrieving instances and will be discussed in its own chapter. − Its createCriteria method selects all rows mapped to the class. − The list method retrieves the populated instances of the Role class objects as a java.util.List collection.
• The contents of the list are already Role objects. Hibernate automatically populates Role instances for each row of the table and adds them to the list. − While Hibernate does not yet use Java-5.0 generics, the code supports their use. − The list method returns an unchecked java.util.List, which is stored in a List. − The Java-5 attribute @SuppressWarnings is then added to the method signature.
© 2006 Ken Kousen. All rights reserved by Capstone Courseware, LLC.
28
Java Persistence with Hibernate
Using Hibernate
Chapter 1
EXAMPLE
• Build and test; the output is the same as from the JDBC version: ant run cc.db.hibernate.PrintRoles (1,user) (2,admin)
• Here, the application is only reading the database. • If modifications are made and something goes wrong, the transaction would need to be rolled back. • To handle that, the code would be wrapped in a try/catch block that catches HibernateException, which is a runtime (i.e., unchecked) exception. − The transaction would be committed at the end of the try block, and if necessary rolled back in the catch block. − The session would be closed in a finally block.
• Hibernate reduces the required coding compared to JDBC. • The differences become more dramatic as the number of classes and tables increases.
© 2006 Ken Kousen. All rights reserved by Capstone Courseware, LLC.
29
Java Persistence with Hibernate
Chapter 1
XML Tools • To support XML authoring in the classroom, a few simple tools have been included with the course software. • One is the Crimson text editor – run this from c:/Capstone/Tools/Crimson3.70/cedit.exe
− You might also create a desktop shortcut to this file, or associate it with text and XML files on your system.
• Another is the XML Validator, which will − parse an XML file for well-formedness − validate a file for correctness against a DTD or XML Schema
• Crimson has been primed with hotkeys that link to these two functions, so that if you edit Spring configurations in Crimson, you can press F9 to parse the file or F10 to validate it against its DTD. − Beware that either of these actions will save the file to disk before running the command – usually a good thing. − Also note that the DTD references are to public URLs; if your machine is not connected to the Internet, F10 validation will fail. − In this case you can replace the public URL with the appropriate local path starting with c:/Capstone/Tools/Hibernate3.2/dtd.
• When working through the exercises in this and the next few chapters, you may find that frequently validating with F10 will help you catch small syntax and grammar errors as you work.
© 2006 Ken Kousen. All rights reserved by Capstone Courseware, LLC.
30
Java Persistence with Hibernate
Chapter 1
Mapping the USERS Table
LAB 1
Suggested time: 30 minutes In this lab you will create the mapping document for the USERS table in the example authentication system, building on the existing files. The goal is to build a User class to model the USERS table, configure Hibernate to use it, and print all the instances of this class. Detailed instructions are found at the end of the chapter.
© 2006 Ken Kousen. All rights reserved by Capstone Courseware, LLC.
31
Java Persistence with Hibernate
Chapter 1
SUMMARY • Object-oriented programming languages and relational databases view their data in very different ways. • Any system using both object-oriented languages and relational databases needs to map the classes to the database tables. • Java provides the JDBC API to enable Java programs to connect to databases, pass SQL statements to them, and process the results. • JDBC programs map classes to tables using SQL statements in a manner that can get tedious and repetitive. • Hibernate describes required mappings in XML documents. • Java programs using Hibernate make conversions from relational data to objects and back again automatic, thus reducing the required Java code considerably.
© 2006 Ken Kousen. All rights reserved by Capstone Courseware, LLC.
32
Java Persistence with Hibernate
Chapter 1
Mapping the USERS Table
LAB 1
In this lab you will create the mapping document for the USERS table in the example authentication system, building on the existing files. Lab workspace:
Labs/Lab1
Backup of starter code:
Examples/UsersRoles/Step1
Answer folder(s):
Examples/UsersRoles/Step2
Files:
src/cc/db/beans/User.java (to be created) src/cc/db/beans/User.hbm.xml (to be created) src/hibernate.cfg.xml src/cc/db/hibernate/PrintUsers.java (to be created)
Instructions: 1. The starter code in the lab directory includes the cc.db.beans.Role class and the cc.db.hibernate.PrintRoles class from the example. It also contains the mapping file for the Role class, Role.hbm.xml, located in the src/cc/db/beans directory, and the overall Hibernate XML configuration file, hibernate.cfg.xml, located in the src directory. Examine these files and see how they interact. 2. Create a class called cc.db.beans.User. Private attributes and public accessors and mutators are required for each column name. The names of the attributes are arbitrary, as long as they appear correctly in the mapping file. For simplicity in this case, use an attribute id of type Integer, and attributes name and password of type String, then add the corresponding getter and setter methods. As a reminder, the USERS table was created from the following SQL DDL statement: CREATE TABLE USERS ( ID INT not null auto_increment, user_name VARCHAR(50), user_pass VARCHAR(50), primary key(id) );
3. To make it easy to print an instance of the User class, add an override for the toString method: public String toString() { return "(" + id + "," + name + "," + password + ")"; }
4. Create a Hibernate mapping file for the User class. Start by copying the file Role.hbm.xml file into User.hbm.xml in the same directory. This ensures that the DOCTYPE declaration in the file is correct.
© 2006 Ken Kousen. All rights reserved by Capstone Courseware, LLC.
33
Java Persistence with Hibernate
Mapping the USERS Table
Chapter 1
LAB 1
5. The root element of the XML file is . It should have an attribute called package with the value cc.db.beans. Please ensure that this is the case. 6. Inside this element, place an element named . It should have an attribute name with the value User, an attribute table with the value USERS, and an attribute catalog with the value authdb. This maps the User class to the USERS table in the authdb schema. 7. The element should have three child elements. The first is , which has an attribute named id of type java.lang.Integer and a child element with an attribute class with value native. 8. The other two child elements of are both elements. One element should have a name attribute with the value name and the other should have a name attribute with the value password. In light of the DDL CREATE statement, each element should also have an attribute called column with the values user_name and user_pass, respectively. 9. Finally, the Hibernate configuration file needs to be updated to include the new User mapping file. Open the file hibernate.cfg.xml and note the element for Role already exists. Add another element below that, with a resource attribute whose value is src/cc/db/beans/User.hbm.xml. In this example, the mapping files are all being stored in the directory src/cc/db/beans. This is, of course, arbitrary, as long as the proper paths are in the Hibernate mapping file. 10. Now that Hibernate has been configured to use the new class, we need a client class to test it. Create a class called PrintUsers in the cc.db.hibernate package by copying the existing class PrintRoles in the same package. 11. The PrintUsers class already has all the code necessary to read all the User instances from the database and print them. All that has to be modified is the call to createCriteria. Change its argument from Role.class to User.class. The rest – building the SessionFactory, getting a Session, beginning a transaction, creating the Criteria query and executing it, printing the results, and shutting everything down, should all be fine. 12. Run the PrintUsers class as a Java application. You should get an output similar to the following: ant run cc.db.hibernate.PrintUsers (1,buffy,slayer) (2,willow,witch)
In a later lab, the many-to-many relationship between User and Role instances will be modeled as well by building on these results.
© 2006 Ken Kousen. All rights reserved by Capstone Courseware, LLC.
34
CHAPTER 2
CONFIGURING HIBERNATE
Java Persistence with Hibernate
Chapter 2
OBJECTIVES After completing “Configuring Hibernate,” you will be able to: • List the required libraries for Hibernate. • Use the Hibernate properties files. • Create an XML configuration file. • Examine the methods involved in programmatic configuration.
© 2006 Ken Kousen. All rights reserved by Capstone Courseware, LLC.
36
Java Persistence with Hibernate
Chapter 2
Hibernate Distributions • In the previous chapter, Hibernate was used to examine the data in a particular database table. • The configuration files for Hibernate were already created and customized. • In this chapter, the structure and content of the overall configuration file is examined in some detail. • The required and optional tags are identified and discussed. • In the next chapter, mapping issues for specific situations will be examined.
© 2006 Ken Kousen. All rights reserved by Capstone Courseware, LLC.
37
Java Persistence with Hibernate
Chapter 2
Hibernate Distributions • The Hibernate project is located at http://www.hibernate.org
• This site always has the latest information on Hibernate. • In addition to the distribution downloads, the site also contains: − A user forum with an archive for historical items − A wiki area for questions and answers − Information about email lists − Links to postings about design patterns, Hibernate Tools, and more
• The current version of Hibernate is 3.2. − Version 3.2 is compatible with the EJB 3.0 specification, part of Java EE 5.
• We will work with version 3.2 in these materials. − Code in practice is normally from versions 2.1 (old), 3.0, and 3.1. − None of the 3.x versions are dramatic variations from each other. − Code using version 2.x is a good candidate to be ported to 3.x.
• Find our Hibernate file set in c:/Capstone/Tools/Hibernate3.2.
© 2006 Ken Kousen. All rights reserved by Capstone Courseware, LLC.
38
Java Persistence with Hibernate
Chapter 2
The Hibernate Distribution • The Hibernate distribution comes as a zipped file which includes the libraries, documentation, and source code. Unzipping the distribution reveals the following directory structure.
− Note that, to keep downloads to a reasonable size and classroom setup simple, our local version is just a subset of this distribution; some of the folders shown above will not appear locally. © 2006 Ken Kousen. All rights reserved by Capstone Courseware, LLC.
39
Java Persistence with Hibernate
Chapter 2
The Hibernate Distribution • The distribution contains the following directories: − doc, which includes the JavaDoc API reference, the Hibernate tutorial, and a PDF file with a Quick Reference guide − eg, which contains a limited version of the Caveat Emptor online auction application that Hibernate uses as its primary demonstration app – we will examine parts of this application in this course − etc, which has configuration-file samples − grammar, which contains files defining the Hibernate Query Language grammar − lib, containing the required and optional JAR files (discussed below) − src, which contains the Hibernate source code1 − test, which has the JUnit test cases for validation
• The root directory also has several files: − An Ant build file used to compile and test the distribution − The hibernate3.jar file, which is needed in every Hibernate application − A readme.txt file and a license file – Hibernate is distributed under the GNU Lesser General Public License
1
Since Hibernate is an open-source project, the latest source code can always be examined, either in the distribution or using the Hibernate Subversion repository. See the Hibernate home page for details.
© 2006 Ken Kousen. All rights reserved by Capstone Courseware, LLC.
40
Java Persistence with Hibernate
Chapter 2
Required Libraries • In addition to hibernate3.jar, the lib directory contains a wide selection of JAR files. • The file _README.txt in this directory indicates which are required and which are optional. • Some of the libraries are used only to build the distribution, while others are needed at runtime. • The required libraries are: − hibernate3.jar, found in the root directory − antlr.jar − asm.jar − asm-attrs.jar − cglib.jar − commons-collections.jar − commons-logging.jar − dom4j.jar − ehcache.jar, required if no other cache provider is used − jta.jar, required for running outside a J2EE container − log4j.jar, not strictly required but recommended
• Also required is the JDBC driver for your database, which must be added for each project. • Note that all library names also contain version numbers.
© 2006 Ken Kousen. All rights reserved by Capstone Courseware, LLC.
41
Java Persistence with Hibernate
Chapter 2
Configuration Files • Two types of configuration files are needed: − One to manage Hibernate itself, meaning the database connections, caching and fetching strategies, and more − One for each of the Java classes in the system – the object/relational mappings for each class
• The basic Hibernate configuration can be done either using a standard properties file or an XML configuration file. • By default, the properties file is hibernate.properties. • A sample version of this file is located in the etc directory and can be customized for individual projects. • A list of available properties is given in the JavaDoc API page for the org.hibernate.cfg.Environment class.
© 2006 Ken Kousen. All rights reserved by Capstone Courseware, LLC.
42
Java Persistence with Hibernate
Chapter 2
hibernate.properties • The hibernate.properties file is divided into several sections, including those listed below. • Query Language − Constraints on HQL, the Hibernate Query Language discussed below
• Platforms − This is where the individual database JDBC driver is configured. − Username, password, and URL properties for many different vendor databases are included in comments.
• Hibernate, C3P0, Proxool, and custom connection pools • Transaction API • Miscellaneous Settings − Examples such as show_sql, format_sql, auto schema export, and others
• JDBC Settings − Isolation levels, fetch depth, autocommit settings, batch updates, and more
• Second-level Cache − Several built-in cache providers are available.
• JNDI − Specifies URL and class for JNDI provider − Used for managed JDBC connection pools
© 2006 Ken Kousen. All rights reserved by Capstone Courseware, LLC.
43
Java Persistence with Hibernate
Chapter 2
hibernate.cfg.xml • Hibernate can also be configured with an XML file, normally called hibernate.cfg.xml. • The format is essentially the same as the properties file, where property names become attributes of the elements and property values become their text contents. • As an example, consider the database configuration properties for MySQL, as listed in the sample hibernate.properties file in the Hibernate distribution: hibernate.connection.driver_class com.mysql.jdbc.Driver hibernate.connection.url jdbc:mysql:///test hibernate.connection.username gavin hibernate.connection.password
• In the sample XML file, this becomes: com.mysql.jdbc.Driver ?"; Connection conn = DriverManager.getConnection("…"); PreparedStatement pst = conn.prepareStatement(sql); pst.setInt(1, 90000); ResultSet rs = pst.executeQuery();
− Each question mark must be replaced by an actual value before the query is executed. − If a query contains multiple parameters, the question marks are numbered from left to right, starting at 1. − If the SQL query changes, the number of parameters and/or their order may change, making maintenance difficult.
• HQL significantly improves on this by using named parameters. − The complete implementation of printEmpsWithHighSalary is: Query q = s.createQuery( "from Employee e where e.salary > :sal"); q.setInteger("sal", 90000); List emps = q.list();
− The parameter name is preceded by a colon. − The parameters still need to be set, but they are keyed by name rather than number. − Note that simple question marks still work, but there is no benefit to using them.
© 2006 Ken Kousen. All rights reserved by Capstone Courseware, LLC.
195
Java Persistence with Hibernate
Chapter 6
Entity Parameters • The named parameter above was set using the setInteger method. • There are similar methods in Query for all the primitive types, as well as setString, setBinary, setCalendar, setDate, and others. • One particularly interesting method is setEntity, which can be used to follow an association with an already-fetched entity. • This can be used, say, to retrieve all Employees that have a particular already-retrieved Job.
© 2006 Ken Kousen. All rights reserved by Capstone Courseware, LLC.
196
Java Persistence with Hibernate
Entity Parameters
Chapter 6
EXAMPLE
• See the printManagers method: String jobHQL = "from Job j where j.name = :name"; Query jobQ = s.createQuery(jobHQL); jobQ.setString("name", "Manager"); Job job = (Job) jobQ.uniqueResult(); String empHQL = "from Employee e where e.job = :job"; Query empQ = s.createQuery(empHQL); empQ.setEntity("job",job); // Use job from above List employees = empQ.list(); for (Employee e : employees) { System.out.println(e.getLastName()); }
− The setEntity method is used in the Employee query to substitute the previously found Job. − Results are: Job is (4,Manager,$50,000.00,$70,000.00) Acosta Barrell House Le Newbie Parks Physh Randolph Ward Wolf
© 2006 Ken Kousen. All rights reserved by Capstone Courseware, LLC.
197
Java Persistence with Hibernate
Ordering
Chapter 6
EXAMPLE
• HQL syntax includes an order by clause. • The order by clause also uses the keywords asc and desc, for ascending and descending, respectively. • As an example, the following query lists Job instances in descending order by maximum salary. − See orderJobsByMaxSalary: Query jobQuery = s.createQuery( "from Job j order by j.maximumSalary desc"); List jobs = jobQuery.list(); for (Job j : jobs) { System.out.println( j.getName() + " " + j.getMaximumSalary()); }
− Results are: DataBase Administrator $120,000.00 President $100,000.00 ... Data Entry Clerk $25,000.00 Junior Engineer $20,000.00
• Multiple order by conditions can be included. The results will be sorted by the first condition, then by the second, and so on.
© 2006 Ken Kousen. All rights reserved by Capstone Courseware, LLC.
198
Java Persistence with Hibernate
Chapter 6
Joining on Associations • Associations allow more than one class to be used in a single HQL query, just as more than one table can be used in a SQL query. select e.lastName, d.name from Employee e inner join e.department as d
• Selecting the entire object is even easier. from Employee e inner join e.department as d
− The returned value is not a List of Employee objects. Instead, it is an Object array whose elements are pairs of Employee instances followed by their associated Department instances.
• Using fetch retrieves associated objects at the same time the query executes. from Department d inner join fetch d.manager as mgr
− The results are a List of Department instances where each already has its Employee manager instance populated.
• The supported join types are inner join, left outer join, right outer join, and full join. • Additional conditions may be appended using the with key word.
© 2006 Ken Kousen. All rights reserved by Capstone Courseware, LLC.
199
Java Persistence with Hibernate
Joining on Associations
Chapter 6
EXAMPLE
• See the highPaidDeptManagers method, which executes this query: from Department as d left join d.manager as mgr with mgr.salary > 90000
− This performs a left outer join, so all Departments are returned and if their managers do not satisfy the salary condition, their values are null. − Results are: Research Bigboote who makes $95,000.00 Administration Zimmerman who makes $97,000.00 Software Development null Hardware Development null Test And Integration null Sales null HR null Facilities null Operations null
© 2006 Ken Kousen. All rights reserved by Capstone Courseware, LLC.
200
Java Persistence with Hibernate
Traversing Associations
Chapter 6
EXAMPLE
• Associations can be traversed as well. The method empsThatManageADept searches for all Employees that manage a Department: select e.lastName, e.managedDepartment.name from Employee e where e.managedDepartment is not null
− Results are: [Bigboote, Research] [Zimmerman, Administration] [Swanson, Software Development] [Walton, Hardware Development] [Church, Test And Integration] [Larsen, Sales] [Gross, HR] [Rollins, Facilities] [Roth, Operations]
− An equivalent query could be run from the Department side: select d.name, d.manager.lastName from Department d where d.manager is not null
© 2006 Ken Kousen. All rights reserved by Capstone Courseware, LLC.
201
Java Persistence with Hibernate
Traversing Associations
Chapter 6
EXAMPLE
• Here’s a rather roundabout way to find all Employees who work in Massachusetts, regardless of where they live – see empsWhoWorkInMA: from Employee e where e.department.location.state = 'MA'
− Results: Anderson lives in MA, works in MA Baxter lives in MA, works in MA ... Rollins lives in MA, works in MA Watts lives in NC, works in MA
• Taking this a step further, empsWhoWorkWhereTheyDontLive finds all Employees who live in one state but work in another: from Employee e where e.address.state != e.department.location.state
− There are 11 such Employees, some of whom live in MA and work in GA, which either means that they have wicked commutes or illustrates the danger of populating a database with random data: Calhoun lives in MA, works in GA Campbell lives in MA, works in GA Espinoza lives in NC, works in GA Farmer lives in MA, works in GA Goodwin lives in NC, works in GA Martin lives in NC, works in GA McConnell lives in MA, works in GA Cardenas lives in NC, works in MA Velez lives in NC, works in MA Nelson lives in GA, works in MA Watts lives in NC, works in MA © 2006 Ken Kousen. All rights reserved by Capstone Courseware, LLC.
202
Java Persistence with Hibernate
Traversing Associations
Chapter 6
EXAMPLE
• That last query required joins across three different tables: EMPLOYEES, DEPARTMENTS, and LOCATIONS. − From the log, the generated SQL was: select employee0_.id as id2_, employee0_.DEPARTMENT_ID as DEPARTMENT2_2_, employee0_.JOB_ID as JOB3_2_, employee0_.firstName as firstName2_, employee0_.middleName as middleName2_, employee0_.lastName as lastName2_, employee0_.GENDER as GENDER2_, employee0_.email as email2_, employee0_.EXTENSION as EXTENSION2_, employee0_.HIREDATE as HIREDATE2_, employee0_.salary as salary2_, employee0_.COMMISSION_PCT as COMMISSION12_2_, employee0_.address as address2_, employee0_.city as city2_, employee0_.state as state2_, employee0_.ZIPCode as ZIPCode2_ from EARTHLINGS.EMPLOYEES employee0_, EARTHLINGS.DEPARTMENTS department1_, EARTHLINGS.LOCATIONS location2_ where department1_.LOCATION_ID=location2_.id and employee0_.DEPARTMENT_ID=department1_.id and location2_.stateemployee0_.state
© 2006 Ken Kousen. All rights reserved by Capstone Courseware, LLC.
203
Java Persistence with Hibernate
Chapter 6
Aggregate Methods • Just as Criteria queries can use projections and aggregates, HQL also supports a range of aggregate methods. • In SQL, the count method determines how many times a given column name appears in a result set. • In HQL, the count method can be used with an asterisk, which counts all the instances of a particular class. select count(*) from Employee e
• The count method can also be used with a property of a class, which counts the number of objects in the result set that have a non-null value for the named property. select count(e.middleName) from Employee e
• The distinct keyword counts only unique values in the row set. select count(distinct e.address.state) from Employee e
• Other aggregate functions include: − The avg(propertyName) method averages a property’s values. − The max(propertyName) and min(propertyName) compute maximum and minimum values of the property, respectively. − The sum(propertyName) method adds up all the property values.
• Multiple aggregates can be used in the same query. select min(e.salary), max(e.salary) from Employee e
© 2006 Ken Kousen. All rights reserved by Capstone Courseware, LLC.
204
Java Persistence with Hibernate
Chapter 6
Updates and Deletes • Despite the focus on queries, as of version 3, HQL can be used to execute bulk updates and deletes. • The Query interface includes the executeUpdate method. public int executeUpdate() throws HibernateException;
• The return value is the number of rows affected by the update or delete. • The HQL statements start with an update or delete, followed by an optional from clause, followed by an optional where clause. update Employee e set e.salary = :newSalary where e.salary = :oldSalary
− After creating this query, the setInteger method would be invoked to set each of the parameters newSalary and oldSalary.
• Delete works the same way. delete from Employee e where e.lastName = :name
− As with any delete statement, be careful with the where clause to avoid losing more data than intended.
© 2006 Ken Kousen. All rights reserved by Capstone Courseware, LLC.
205
Java Persistence with Hibernate
Chapter 6
Hibernate Queries
LAB 6
Suggested time: 30 minutes In this lab you will create HQL queries to answer the same questions about the Earthlings database examined in the Criteria query chapter. Detailed instructions are found at the end of the chapter.
© 2006 Ken Kousen. All rights reserved by Capstone Courseware, LLC.
206
Java Persistence with Hibernate
Chapter 6
Named Queries • Another feature of HQL is that the queries themselves don’t have to be included in the source code. • Instead, queries are added to the mapping files and given a name. • The truly interesting part is that native SQL queries can also be added to the mapping files. − Native SQL queries are also given names. − The code then executes a named query without distinguishing between HQL and SQL queries. − This provides a migration path for SQL-based applications.
• In the mapping file, use the element for HQL queries and the element for SQL queries. − Any elements follow the element.
• The queries themselves are normally placed in a CDATA section. • This tells the XML parser not to try to parse the query as XML. − Among other problems, a simple less-than comparison would not be well-formed XML.
© 2006 Ken Kousen. All rights reserved by Capstone Courseware, LLC.
207
Java Persistence with Hibernate
A Named Query
Chapter 6
EXAMPLE
• Meanwhile, back in Examples/Earthlings/Step8, Employee.hbm.xml includes a new : :salary ]]>
• The method namedQuery executes this query: Query empQuery = s.getNamedQuery("Employees.by.state.and.salary") .setString("state", "MA") .setInteger("salary", 50000); List emps = empQuery.list(); for (Employee e : emps) { System.out.println(e.getLastName() + " lives in " + e.getAddress().getState() + " and makes " + e.getSalary()); }
− The results are: run cc.db.hibernate.HQLQueries Baxter lives in MA and makes 82000.0 Estrada lives in MA and makes 53000.0 Gross lives in MA and makes 76000.0 Rollins lives in MA and makes 80000.0 Smythe lives in MA and makes 64000.0 Zimmerman lives in MA and makes 97000.0
© 2006 Ken Kousen. All rights reserved by Capstone Courseware, LLC.
208
Java Persistence with Hibernate
Chapter 6
Using Native SQL • Hibernate recommends using HQL wherever possible. • Reasons to use native SQL include: − Your database supports some special features not available in HQL. − You plan to call stored procedures from a Hibernate application. − You have an existing base of SQL queries that you have not yet ported to HQL.
• The SQL queries need to be modified to include Hibernate aliases that correspond to objects or object properties. − Use the syntax {objectname.*} to refer to all properties on an object. − Use {objectname.property} to refer to specific properties. − Hibernate then uses the mapping files to translate these aliases to the proper SQL columns.
• Hibernate uses the org.hibernate.SQLQuery interface for native SQL. − SQLQuery is a subinterface of Query. − Use the createSQLQuery factory method on Session to create a SQL query. public SQLQuery createSQLQuery(String query) throws HibernateException
• The query must then be associated with an existing Hibernate entity, join, or scalar result.
© 2006 Ken Kousen. All rights reserved by Capstone Courseware, LLC.
209
Java Persistence with Hibernate
Native SQL Queries
Chapter 6
EXAMPLE
• printJobsUsingSQL selects all Jobs using a SQL query: List jobs = s.createSQLQuery("select {j.*} from JOBS j") .addEntity("j", Job.class).list(); for (Job j : jobs) { System.out.println(j); }
− This form of the addEntity method takes two parameters. The first is a string representing the alias, and the second is the entity class. − Results are: President Vice President ... CIO Test Designer
• printAvgSalaryUsingSQL finds the average salary: List aveSalary = s.createSQLQuery( "select avg(e.salary) as avgSal from EMPLOYEES e") .addScalar("avgSal", Hibernate.DOUBLE).list(); System.out.println(aveSalary);
− Scalar quantities use the addScalar method. − The returned List has a single element containing the average of the salaries: [43866.6667]
© 2006 Ken Kousen. All rights reserved by Capstone Courseware, LLC.
210
Java Persistence with Hibernate
Chapter 6
SUMMARY • Hibernate defines HQL, the Hibernate Query Language. • HQL is fully object-oriented, with an understanding of associations, inheritance, and polymorphism. • HQL provides named parameters so that parameters can be set using a String key instead of counting question marks in a PreparedStatement. • HQL includes aggregate functions as well as native SQL functions where they are supported by the underlying database. • HQL queries can be saved in the mapping files and then called by name in Java code. • Though normally HQL is used for queries, the current version of Hibernate supports bulk updates and deletes. • HQL supports execution of native SQL queries.
© 2006 Ken Kousen. All rights reserved by Capstone Courseware, LLC.
211
Java Persistence with Hibernate
Chapter 6
Hibernate Queries
LAB 6
In this lab you will create HQL queries to answer the same questions about the Earthlings database examined in the Criteria query chapter. Lab workspace:
Labs/Lab6
Backup of starter code:
Examples/Earthlings/Step8
Answer folder(s):
Examples/Earthlings/Step9
Files:
src/cc/db/hibernate/HQLLab.java
Instructions: Open the file HQLLab.java. This class has an execute method that demarcates a transaction. In the transaction, call private methods that you create in order to answer the following questions using HQL queries. 1. How many Employee instances are in the database? 2. What are the names of the Employees in the Administration department? 3. What is the Location of the Research department? 4. What is the average salary of Employees in the Research department? 5. What query finds the Employees sorted by last name?
© 2006 Ken Kousen. All rights reserved by Capstone Courseware, LLC.
212
APPENDIX A
LEARNING RESOURCES
Java Persistence with Hibernate
© 2006 Ken Kousen. All rights reserved by Capstone Courseware, LLC.
Appendix A
214
Java Persistence with Hibernate
Appendix A
Books Bauer, King, Expert Java Persistence with Hibernate, Manning. This recently re-written second edition of the main Hibernate text, includes sections on annotations, JPA, Seam, and more. This is the primary book in the field.
Bauer, King, Hibernate in Action, Manning. This is the first edition of the above book, from the lead developers of the framework.
Minter, Linwood, Pro Hibernate 3, Apress. An interesting approach to Hibernate development, focusing on usability.
Hemrajani, Agile Java Development with Spring, Hibernate and Eclipse, Sams. Iverson, Hibernate: A J2EE Developer’s Guide, Addison-Wesley. The content is a bit dated and highly opinionated, but has good recommendations from an individual unconnected to the Hibernate project.
Elliott, Hibernate: A Developer’s Notebook, O’Reilly Media. The content is quick and easy and highly interactive, but is based on Hibernate 2.
Alur, Crupi, Malks, Core J2EE Design Patterns, Sun Microsystems Press. The best-known work on J2EE patterns with definitive information on DAO, etc.
© 2006 Ken Kousen. All rights reserved by Capstone Courseware, LLC.
215
Java Persistence with Hibernate
Appendix A
Specifications and Technical Documentation The Hibernate home page: http://hibernate.org Bookmark – reference manual: http://www.hibernate.org/hib_docs/v3/reference/en/html/ Bookmark – Wiki community area: http://hibernate.org/37.html
Web Resources Hibernate 3.1 Used with Tomcat 5.5.x: http://www.theserverside.com/tt/articles/article.tss?l=HibernateTomcat Hibernate vs. Rails: The Persistence Showdown http://www.theserverside.com/tt/articles/article.tss?l=RailsHibernate Using Spring and Hibernate with WebSphere Application Server: http://www-128.ibm.com/developerworks/websphere/techjournal /0609_alcott/0609_alcott.html Don’t Repeat the DAO! http://www-128.ibm.com/developerworks/java/library/j-genericdao.html The JBoss IDE project http://labs.jboss.com/portal/jbosside The MyEclipse IDE http://www.myeclipseide.com/
© 2006 Ken Kousen. All rights reserved by Capstone Courseware, LLC.
216