This project steps back from "Spring Magic" to show how the Jakarta Persistence API (JPA) actually works under the hood. It demonstrates the explicit lifecycle management of Java entities—from creation and persistence to querying—using the EntityManager.
Configured in persistence.xml, the Persistence Unit is the configuration set that defines how the application connects to the database.
RESOURCE_LOCAL: Indicates that we are managing transactions manually in our code rather than relying on a Java EE Application Server.- JAXB Runtime: Included in the
pom.xmlbecause modern Java versions (like your Java 25) have removed the built-in XML binding libraries needed to parse the persistence config.
EntityManagerFactory: An expensive, thread-safe object created once per application lifetime. It represents the database structure.EntityManager: A lightweight object used for a single "unit of work." It is the primary interface used to interact with the persistence context.
In this project, you see the begin() and commit() calls.
- Manual Control: Unlike
@Transactionalin Spring, here we manually wrap our work in transactions to ensure Atomicity (either everything saves, or nothing does).
@Entity: Marks the class for optimization by the persistence provider (Hibernate).GenerationType.IDENTITY: Tells MySQL to use itsAUTO_INCREMENTfeature to handle primary keys.
This class contains the lifecycle logic:
persist(): Moves an object from the "Transient" state to the "Managed" state.- JPQL Query: Uses
SELECT p FROM Product p. Notice we query the Class Name (Product), not the table name (products). JPA translates this to SQL automatically.
The heart of the connection.
hibernate.hbm2ddl.auto = update: Automatically creates or modifies the MySQL table structure to match your Java class.- SSL REQUIRED: Configured for secure connection to cloud-hosted MySQL (Aiven).
- Java 25: Utilizing the latest JVM features.
- Spring Boot 4.0.1 (BOM): Used here primarily for dependency version management.
- Hibernate 6.x: The most popular JPA implementation.
- MySQL 9.3: The latest relational database driver.
- Bootstrap:
Persistence.createEntityManagerFactory("example-unit")reads your XML config. - Session Start: An
EntityManageris opened. - Write: Two
Productobjects are created, "persisted" into the context, and "committed" to the MySQL cloud database. - Read: A JPQL query fetches all records and prints them to the console.
- Cleanup: Both the Manager and Factory are closed to prevent memory leaks.
- MySQL Setup: Ensure your Aiven MySQL instance is running and accessible.
- Run: Execute the
MainApp. - Verify:
- Watch the console. Because
hibernate.show_sqlistrue, you will see the exactINSERTandSELECTstatements Hibernate generates. - Example Output:
Hibernate: insert into products (name, price) values (?, ?) Products ID: 1, Name: Product-1, Price: 10.99
- Watch the console. Because