The Persistence
class has a createEntityManagerFactory
method to which we pass the name of a persistence unit. Recall that in our persistence.xml
file we defined a single persistence-unit
with the name "Books." The call to createEntityManagerFactory
creates an EntityManagerFactory
that will to connect this database with its configuration, including the Book
and Author
entity classes. We then use the EntityManagerFactory
to create an EntityManager
:
EntityManager entityManager = entityManagerFactory.createEntityManager();
Next, we create our repositories, passing the EntityManager
to their constructors.
Now we're ready we exercise the repositories.
CRUD operations on the example application
First, we create an author. We add three books to the author, then save it by invoking the AuthorRepository::save
method. Here's the resulting output:
Saved author: Author{id=1, name='Author 1', books=[Book{id=2, name='Book 1', author=Author 1}, Book{id=3, name='Book 2', author=Author 1}, Book{id=4, name='Book 3', author=Author 1}]}
Recall that we set the Author
's @OneToMany
annotation to use a CascadeType
of ALL
. Because of this, when we save the author all of its books will also be saved. As the output shows, the author is saved first. It gets an auto-generated primary key value of 1, then the author's three books are saved.
Next, we retrieve all authors by executing the AuthorRepository::findAll
method. We have just one author, so this code yields the following output:
Authors:
Author{id=1, name='Author 1', books=[Book{id=2, name='Book 1', author=Author 1}, Book{id=3, name='Book 2', author=Author 1}, Book{id=4, name='Book 3', author=Author 1}]}
We search for an author by name by executing the AuthorRepository::findByName
method, passing it the name "Author 1". This yields the following output:
Searching for an author by name:
Author{id=1, name='Author 1', books=[Book{id=2, name='Book 1', author=Author 1}, Book{id=3, name='Book 2', author=Author 1}, Book{id=4, name='Book 3', author=Author 1}]}
We execute two book queries by ID, one that should be found, namely the book with ID 2, and one that should not be found, namely one with ID 99. As expected we see only one record printed out:
Book{id=2, name='Book 1', author=Author 1}
We query for all books by executing the BookRepository::findAll
method, which successfully shows all books:
Books in database:
Book{id=2, name='Book 1', author=Author 1}
Book{id=3, name='Book 2', author=Author 1}
Book{id=4, name='Book 3', author=Author 1}
We exercise our queries to find books by name, one using the raw JPQL query, BookRepository::findByName
, and one using the named query, BookRepository::findByNameNamedQuery
:
Query for book 2:
Book{id=3, name='Book 2', author=Author 1}
Query for book 3:
Book{id=4, name='Book 3', author=Author 1}
Finally, we retrieve the author with ID 1, add a new book to the author's list of books, save the author, and output the saved author, expecting to now see four books in the list:
Saved author: Optional[Author{id=1, name='Author 1', books=[Book{id=2, name='Book 1', author=Author 1}, Book{id=3, name='Book 2', author=Author 1}, Book{id=4, name='Book 3', author=Author 1}, Book{id=5, name='Book 4', author=Author 1}]}]
When we're finished with all of our queries, we need to close both the EntityManager
and the EntityManagerFactory
; otherwise their threads will live on and our application will never complete:
entityManager.close();
entityManagerFactory.close();
Run the example application
Running the application is simple.
Step 1: Build with Maven:
mvn clean install
Step 2: Change directories into the target
directory and execute the JAR file:
cd target
java -jar jpa-example-1.0-SNAPSHOT.jar
Conclusion
This tutorial has been a general introduction to JPA with Hibernate. We've reviewed JPA as a standard for ORM in Java and looked at how entities, relationships, and the EntityManager
work together in your Java applications.
In the second half of this tutorial we'll build a new example application that explores one of JPA's more complicated relationship types: the bidirectional, many-to-many relationship. The example will allow you to practice and deepen what you already know about entity relationships and the EntityManager
. You'll also learn about lazy and eager fetching strategies, working with join tables, and how to choose the right CascadeType
.
This story, "Java persistence with JPA and Hibernate, Part 1: Entities and relationships" was originally published by JavaWorld.