JPA Book Exercise
Exercise 1: Mapping Entities and Annotations
Objective: Apply JPA annotations to map Java classes to database tables and understand entity lifecycle.
- Set Up a Java Project:
- Create a new Maven project. Use JPA starter if needed.
- Define the
Book
Entity:- Create a simple entity class called
Book
with the following attributes:id
(primary key)title
author
isbn
(must be unique)publishedYear
- Use JPA annotations to map the entity class to a database table named
books
. - Ensure the
isbn
field is unique. - Include a no-arg constructor (
@NoArgsConstructor
). - Add Lombok annotations like
@Getter
,@Setter
,@ToString
, and@Builder
.
- Create a simple entity class called
- Add JPA Annotations:
- Use
@Entity
,@Table
,@Id
,@GeneratedValue
, and@Column
to define the primary key and attribute mappings.
- Use
- Set Up the
Main
Class:- Add a static property:
EntityManagerFactory
. -
Create methods for CRUD operations in a
BookDAO
class: public static void createBook(Book book)
- This method persists a new book to the database.
public static Book readBook(int id)
- This method retrieves a book by ID.
public static Book updateBook(Book updatedBook)
- This method updates an existing book.
public static void deleteBook(int id)
- This method deletes a book by ID.
public static List<Book> readAllBooks()
- This method retrieves all books from the database using a
TypedQuery
.
- This method retrieves all books from the database using a
- Add a static property:
-
Use
try-with-resources
orfinally
blocks to properly closeEntityManager
objects. - Add JPA Entity Lifecycle Comments
- Add comments explaining when an entity is in:
- Transient State (before persist)
- Managed State (after persist)
- Detached State (after transaction commit)
- Removed State (before deletion)
Example:
public static void main(String[] args) { // Entity is in transient state Book book = new Book("Effective Java", "Joshua Bloch", "9780134685991", 2018); } public static void createBook(Book book) { try (EntityManager em = emf.createEntityManager()) { em.getTransaction().begin(); // Entity is in managed state after persist() em.persist(book); // Entity becomes detached after transaction is committed em.getTransaction().commit(); } }
- Add comments explaining when an entity is in:
- Validate ISBN Before Persisting a Book
- Add a method in the
Book
class to verify that the ISBN is valid. - Use
@PrePersist
to validate ISBN before saving a book. - If ISBN is invalid, throw an exception.
- Add a
@PreUpdate
method to validate ISBN before updating. - Hint: Use the
ISBNValidator
class from the ISBN validation exercise
- Add a method in the
- Create a Test Class
- Add a test class that contains a test method for each CRUD operation. It’s not an integration test, but just a sort of
main
method that calls each method in theBookDAO
class.
- Add a test class that contains a test method for each CRUD operation. It’s not an integration test, but just a sort of
- Populate the Database with Books
- Add 10 books to the database
- At least 3 books should be authored by “J.K. Rowling”
- At least 4 books should be authored by “George Orwell”
- The oldest book should be from 1945
- The most recent book should be from 2024
- Aggregate Data with Queries
- Calculate the average publication year of all books
- Find the average publication year of books authored by “George Orwell”
- Count how many books are authored by “J.K. Rowling”
- Find the title of the oldest book** in the database.
- Retrieve the most recently published book
- Sum the publication years of all books
Exercise 2: Q & A
- Why do we need a no-arg constructor in an entity class?
- Investigate where in the code we can:
- Specify the database dialect?
- Define JDBC connection properties?
- Add annotated classes?
- What is the purpose of
@GeneratedValue
?- What are the different primary key generation strategies in JPA?
- What is
try-with-resources
, and how can we use it in JPA? - What is the difference between
persist()
andmerge()
in JPA? - What is the difference between
TypedQuery
andQuery
? - What is the difference between
getSingleResult()
andgetResultList()
? - What are the different states of an entity in JPA?