Main Program
We need to create an environment in which instances of the entity class can be created. Listing 3 shows a complete class that builds the environment and instantiates and persists our entities.
Listing 3 A client program.
import java.util.*; import javax.persistence.*; public class HelloWorld { public static void main(String[] args) { // Start EntityManagerFactory EntityManagerFactory emf = Persistence.createEntityManagerFactory("helloworld"); // First unit of work EntityManager em = emf.createEntityManager(); EntityTransaction tx = em.getTransaction(); tx.begin(); Message message = new Message("Hello World with JPA"); em.persist(message); tx.commit(); em.close(); // Second unit of work EntityManager newEm = emf.createEntityManager(); EntityTransaction newTx = newEm.getTransaction(); newTx.begin(); List messages = newEm.createQuery("select m from Message m order by m.text asc").getResultList(); System.out.println( messages.size() + " message(s) found:" ); for (Object m : messages) { Message loadedMsg = (Message) m; System.out.println(loadedMsg.getText()); } newTx.commit(); newEm.close(); // Shutting down the application emf.close(); } }
Listing 3 is divided into "units of work"—transactions in which instances of the entity are created and persisted into the database. Once persisted, the instances are retrieved and displayed to the console.
Installation
The only real installation in the "Hello World" code is unpacking the zip file into a folder. As is often the case with Java code, you should keep the target folder path short and avoid any spaces. On my system, I unpacked the zip file into a folder called C:\java, which resulted in the following directory structure:
C:\java\jpwh-gettingstarted-070401\helloworld-jpa
To run the code, you simply open a DOS console and change to the above directory (described next).
Running the Code
The easiest way to run the code is to open three DOS consoles in the directory containing the Ant build file (called build.xml). To view the Ant build targets, enter the following command:
ant –p
You should see something like Listing 4.
Listing 4 Viewing the Ant targets.
C:\java\jpwh-gettingstarted-070401\helloworld-jpa>ant -p Buildfile: build.xml Main targets: clean Clean the build directory dbmanager Start HSQL DB manager run Build and run HelloWorld schemaexport Exports a generated schema to DB and file startdb Run HSQL database server with clean DB Default target: compile
The following three sections describe how to do the following:
- Start the database manager.
- Export the schema to the database.
- Run the client program.
The easiest way to perform these tasks is to run the appropriate command from a separate DOS console. In other words, open each DOS console in the following folder:
C:\java\jpwh-gettingstarted-070401\helloworld-jpa
Then execute the appropriate Ant target as described in the following sections.
Starting the Database Manager
You'll be glad to hear that to run the code, you don't have to spend ages setting up a database manager. The example program uses an in-memory database called HSQLDB. Of course, you can change the configuration and use any database you like, but the example includes HSQLDB by default. To start the database manager, type the command illustrated in Listing 5.
Listing 5 Running the database engine.
C:\java\jpwh-gettingstarted-070401\helloworld-jpa>ant startdb Buildfile: build.xml startdb: [delete] Deleting directory C:\java\jpwh-gettingstarted-070401\helloworld-jpa\database [java] [Server@1d58aae]: [Thread[main,5,main]]: checkRunning(false) entered [java] [Server@1d58aae]: [Thread[main,5,main]]: checkRunning(false) exited [java] [Server@1d58aae]: Startup sequence initiated from main() method [java] [Server@1d58aae]: Loaded properties from [C:\java\jpwh-gettingstarted-070401\helloworld-jpa\server.properties] [java] [Server@1d58aae]: Initiating startup sequence... [java] [Server@1d58aae]: Server socket opened successfully in 15 ms. [java] [Server@1d58aae]: Database [index=0, id=0, db=file:database/db, alias=] opened sucessfully in 375 ms. [java] [Server@1d58aae]: Startup sequence completed in 390 ms. [java] [Server@1d58aae]: 2008-12-04 11:17:19.187 HSQLDB server 1.8.0 is online [java] [Server@1d58aae]: To close normally, connect and execute SHUTDOWN SQL [java] [Server@1d58aae]: From command line, use [Ctrl]+[C] to abort abruptly
When you see something like the results shown in Listing 5, you should be ready to export the schema to the database.
Exporting the Schema to the Database
To populate the database, you must create a schema file, which is nothing more than a file containing SQL code to create and configure your tables. The schema can be created and exported all at once with the command in Listing 6.
Listing 6 Exporting the schema.
C:\java\jpwh-gettingstarted-070401\helloworld-jpa>ant schemaexport Buildfile: build.xml compile: copymetafiles: schemaexport: [hibernatetool] Executing Hibernate Tool with a JPA Configuration [hibernatetool] 1. task: hbm2ddl (Generates database schema) [hibernatetool] [hibernatetool] alter table MESSAGES [hibernatetool] drop constraint FK131AF14C3CD7F3EA; [hibernatetool] [hibernatetool] drop table MESSAGES if exists; [hibernatetool] [hibernatetool] create table MESSAGES ( [hibernatetool] MESSAGE_ID bigint generated by default as identity (start with 1), [hibernatetool] MESSAGE_TEXT varchar(255), [hibernatetool] NEXT_MESSAGE_ID bigint, [hibernatetool] primary key (MESSAGE_ID) [hibernatetool] ); [hibernatetool] [hibernatetool] alter table MESSAGES [hibernatetool] add constraint FK131AF14C3CD7F3EA [hibernatetool] foreign key (NEXT_MESSAGE_ID) [hibernatetool] references MESSAGES; [hibernatetool] 1 errors occurred while performing <hbm2ddl>. [hibernatetool] Error #1: java.sql.SQLException: Table not found: MESSAGES in statement [alter table MESSAGES] BUILD SUCCESSFUL
All that happens in Listing 6 is the creation of a schema file and exporting that file into the database engine. If you want to see the schema file, look in the home folder for a file called helloworld-jpa-ddl.sql. The contents of this file are shown in Listing 7.
Listing 7 The auto-generated schema.
alter table MESSAGES drop constraint FK131AF14C3CD7F3EA; drop table MESSAGES if exists; create table MESSAGES ( MESSAGE_ID bigint generated by default as identity (start with 1), MESSAGE_TEXT varchar(255), NEXT_MESSAGE_ID bigint, primary key (MESSAGE_ID) ); alter table MESSAGES add constraint FK131AF14C3CD7F3EA foreign key (NEXT_MESSAGE_ID) references MESSAGES;
Listing 7 demonstrates some of the magic of JPA. This SQL code was generated based on the annotated Java code. You can see how JPA transparently bridges the Java and relational database worlds.
The error message at the end of Listing 6 merely reflects the fact that the MESSAGES table didn't exist prior to running the script. So, if all has gone well, you should now have a fully created (though not yet populated) database. Let's examine this database.
Starting the Database Manager
The HSQLDB product includes a useful GUI-driven database manager. You can run this manager with the command in Listing 8.
Listing 8 Running the database manager.
C:\java\jpwh-gettingstarted-070401\helloworld-jpa>ant dbmanager Buildfile: build.xml dbmanager: [java] Failed to load preferences. Proceeding with defaults: [java]
Don't worry about the diagnostic message in Listing 8—it relates to a missing configuration file. The important point is that you should see a new window similar to the one in Figure 1.
Figure 1 The HSQL Database Manager GUI.
I've executed a SQL query in Figure 1 to illustrate that the database contains no data. It's easy to run SQL with the GUI—just select Command > Select. This loads the text SELECT * FROM and you just append the name of the table—in this example, the table MESSAGES. Once the command is typed, click the Execute SQL button. At this point, you should see something like that illustrated in the lower-right section of Figure 1. The problem is that there's no data! Let's remedy this situation.