“Hello World" with JPA


In this section, you’ll write your first Hibernate application, which stores a “Hello World” message in the database and then retrieves it. Let’s start by installing and configuring Hibernate.
We use Apache Maven as the project build tool. Declare the dependency on Hibernate:

<dependency>
<groupId>org.hibernate</groupId>
   <artifactId>hibernate-entitymanager</artifactId>
   <version>5.0.0.Final</version>
</dependency>


The hibernate-entitymanager module includes transitive dependencies on other modules you’ll need, such as hibernate-core and the Java Persistence interface stubs.
Your starting point in JPA is the persistence unit. A persistence unit is a pairing of your domain model class mappings with a database connection, plus some other configuration settings. Every application has at least one persistence unit; some applications have several if they’re talking to several (logical or physical) databases. Hence, your first step is setting up a persistence unit in your application’s configuration.

1 -  Configuring a persistence unit

The standard configuration file for persistence units is located on the classpath in META-INF/persistence.xml. Create the following configuration file for the “Hello World” application:



1 -  The persistence.xml file configures at least one persistence unit; each unit must have a unique name.

2 - Each persistence unit must have a database connection. Here you delegate to an existing java.sql.DataSource. Hibernate will find the data source by name with a JNDI lookup on startup.

3 - A persistent unit has persistent (mapped) classes. You list them here.

4 - Hibernate can scan your classpath for mapped classes and add them automatically to your persistence unit. This setting disables that feature.

5 - Standard or vendor-specific options can be set as properties on a persistence unit. Any standard properties have the javax.persistence name prefix; Hibernate’s settings use hibernate.

6 - The JPA engine should drop and re-create the SQL schema in the database automatically when it boots. This is ideal for automated testing, when you want to work with a clean database for every test run.
H When printing SQL in logs, let Hibernate format the SQL nicely and generate comments into the SQL string so you know why Hibernate executed the SQL statement. Most applications need a pool of database connections, with a certain size and optimized thresholds for the environment. You also want to provide the DBMS host and credentials for your database connections.
Logging SQL

All SQL statements executed by Hibernate can be logged—an invaluable tool during optimization. To log SQL, in persistence.xml, set the properties hibernate .format_sql and hibernate.use_sql_comments to true. This will cause Hibernate to format SQL statements with causation comments. Then, in your logging configuration (which depends on your chosen logging implementation), set the categories org.hibernate.SQL and org.hibernate.type.descriptor.sql.BasicBinder to the finest debug level. You'll then see all SQL statements executed by Hibernate in your log output, including the bound parameter values of prepared statements.
For the “Hello World” application, you delegate database connection handling to a Java Transaction API (JTA) provider, the open source Bitronix project. Bitronix offers connection pooling with a managed java.sql.DataSource and the standard javax. transaction.UserTransaction API in anyJava SE environment. Bitronix binds these objects into JNDI, and Hibernate interfaces automatically with Bitronix through JNDI lookups. Setting up Bitronix in detail is outside of the scope of this book; you can find the configuration for our examples in org.jpwh. env.TransactionManagerSetup.
In the “Hello World” application, you want to store messages in the database and load them from the database. Hibernate applications define persistent classes that are mapped to database tables. You define these classes based on your analysis of the business domain; hence, they’re a model of the domain. This example consists of one class and its mapping. Let’s see what a simple persistent class looks like, how the mapping is created, and some of the things you can do with instances of the persistent class in Hibernate.

2 -  Writing a persistent class

The objective of this example is to store messages in a database and retrieve them for display. The application has a simple persistent class, Message:

1 -  Every persistent entity class must have at least the @Entity annotation. Hibernate maps this class to a table called MESSAGE.
2 -  Every persistent entity class must have an identifier attribute annotated with @Id.
Hibernate maps this attribute to a column named ID.
3 -  Someone must generate identifier values; this annotation enables automatic generation of IDs.
4 -  You usually implement regular attributes of a persistent class with private or protected fields and public getter/setter method pairs. Hibernate maps this attribute to a column called TEXT.
The identifier attribute of a persistent class allows the application to access the database identity—the primary key value—of a persistent instance. If two instances of Message have the same identifier value, they represent the same row in the database.
This example uses Long for the type of the identifier attribute, but this isn’t a requirement. Hibernate allows virtually anything for the identifier type, as you’ll see later.
You may have noticed that the text attribute of the Message class has JavaBeans-style property accessor methods. The class also has a (default) constructor with no parameters. The persistent classes we show in the examples will usually look something like this. Note that you don’t need to implement any particular interface or extend any special superclass.
Instances of the Message class can be managed (made persistent) by Hibernate, but they don’t have to be. Because the Message object doesn’t implement any persistence-specific classes or interfaces, you can use it just like any other Java class:
Message msg = new Message(); msg.setText("Hello!");
System.out.println(msg.getText());
It may look like we’re trying to be cute here; in fact, we’re demonstrating an important feature that distinguishes Hibernate from some other persistence solutions. You can use the persistent class in any execution context—no special container is needed.
You don’t have to use annotations to map a persistent class. Later we’ll show you other mapping options, such as the JPA orm.xml mapping file, and native hbm.xml mapping files, and when they’re a better solution than source annotations.
The Message class is now ready. You can store instances in your database and write queries to load them again into application memory.

3 -  Storing and loading messages

What you really came here to see is Hibernate, so let’s save a new Message to the database. First you need an EntityManagerFactory to talk to your database. This API represents your persistence unit; most applications have one EntityManagerFactory for one configured persistence unit:
EntityManagerFactory emf =
Persistence.createEntityManagerFactory("HelloWorldPU");
Once it starts, your application should create the EntityManagerFactory; the factory is thread-safe, and all code in your application that accesses the database should share it.
You can now work with the database in a demarcated unit—a transaction—and store a Message:
1 -  Get access to the standard transaction API UserTransaction, and begin a transaction on this thread of execution.
2 -  Begin a new session with the database by creating an EntityManager. This is your context for all persistence operations.
3 -  Create a new instance of the mapped domain model class Message, and set its text property.
4 -  Enlist the transient instance with your persistence context; you make it persistent. Hibernate now knows that you wish to store that data, but it doesn't necessarily call the database immediately.
5 -  Commit the transaction. Hibernate automatically checks the persistence context and executes the necessary SQL INSERT statement.
6 -  If you create an EntityManager, you must close it.
To help you understand how Hibernate works, we show the automatically generated and executed SQL statements in source code comments when they occur. Hibernate inserts a row in the MESSAGE table, with an automatically generated value for the ID primary key column, and the TEXT value.
You can later load this data with a database query:

1 -  Every interaction with your database should occur within explicit transaction boundaries, even if you’re only reading data.
2 -  Execute a query to retrieve all instances of Message from the database.
3 -  You can change the value of a property. Hibernate detects this automatically because the loaded Message is still attached to the persistence context it was loaded in.
4 -  On commit, Hibernate checks the persistence context for dirty state and executes the SQL UPDATE automatically to synchronize in-memory with the database state.

The query language you’ve seen in this example isn’t SQL, it’s the Java Persistence Query Language (JPQL). Although there is syntactically no difference in this trivial example, the Message in the query string doesn’t refer to the database table name, but to the persistent class name. If you map the class to a different table, the query will still work.
Also, notice how Hibernate detects the modification to the text property of the message and automatically updates the database. This is the automatic dirty-checking feature of JPA in action. It saves you the effort of explicitly asking your persistence manager to update the database when you modify the state of an instance inside a transaction.
You’ve now completed your first Hibernate and JPA application. Maybe you’ve already noticed that we prefer to write examples as executable tests, with assertions that verify the correct outcome of each operation. We’ve taken all the examples in this book from test code, so you (and we) can be sure they work properly. Unfortunately, this also means you need more than one line of code to create the EntityManager-Factory when starting the test environment. We’ve tried to keep the setup of the tests as simple as possible. You can find the code in org.jpwh.env.JPASetup and org .jpwh. env. JPATest; use it as a starting point for writing your own test harness.
Before we work on more-realistic application examples, let’s have a quick look at the native Hibernate bootstrap and configuration API.


Comments