Week 1 — Lab Projects

Jakarta EE Environment Setup & Your First JPA Project

Part 1: Install JDK, MySQL, and NetBeans
Part 2: Build and run a JPA application that persists a Book entity

Stephen Vu — Tutor
A complete NetBeans sample project is available on the Week 1 block of the unit Moodle site.

Overview

What We're Building Today

By the end of this lab, you will have a working development environment and a running Java application that writes data to a MySQL database using JPA — without writing a single line of SQL.

Part 1

Environment Setup

Install and configure the three tools you'll use for the rest of this unit: JDK 21 (the compiler), MySQL (the database), and NetBeans (the IDE). You'll verify each installation before moving on.

Part 2

First JPA Project

Create a Java application that defines a Book entity, configures JPA with EclipseLink, connects to MySQL, and persists a book record. You'll see the data appear in your database.

Before you start: This guide is written for Windows. If you're on macOS or Linux, the software is the same but the installation steps differ — search for platform-specific instructions where needed.
1

Environment Setup

Installing and configuring JDK, MySQL, and NetBeans — the foundation for every project in this unit.

Part 1

Software You'll Install

Each tool serves a specific role in the Jakarta EE stack. Understanding why you need each one helps when troubleshooting later.

JDK 21
The Java compiler and runtime. Every piece of code you write compiles against this. Environment variables tell other tools where to find it.
Version 21 (LTS)
MySQL
The relational database that stores your application data. You need three components: the Server (runs the database), Workbench (GUI to inspect data), and Connector/J (JDBC driver so Java can talk to MySQL).
Version 8.0.29+
NetBeans IDE
Your integrated development environment. Provides project management, code editing, debugging, and built-in support for JPA entity creation and database connections.
Version 20+
GlassFish (the application server) is not needed until Week 5. Don't install it yet — it will be covered in its own lab.

Part 1 — Step 1

Install JDK 21

A

Download and run the installer

Go to oracle.com/java/technologies/downloads/#jdk21-windows and download the .exe installer for JDK 21. Run it with default settings.

B

Set environment variables

Open Control Panel → System → Advanced System Settings → Environment Variables. Create the variables listed in the table to the right.

C

Verify the installation

Open a new Command Prompt (existing ones won't see the new variables) and run the two commands below.

> java -version java version "21.0.1" 2023-10-17 LTS > javac -version javac 21.0.1

Environment Variables to Set

VariableValue
JAVA_HOMEC:\Program Files\Java\jdk-21
JDK_HOMEC:\Program Files\Java\jdk-21

Then add to the PATH variable:

%JAVA_HOME%\bin %JDK_HOME%\bin
Why environment variables? Other tools (NetBeans, GlassFish, build scripts) look for JAVA_HOME to locate the JDK. Without it, they can't find the compiler.

Part 1 — Step 2

Install MySQL

A

Download the MySQL Community Installer

Go to dev.mysql.com/downloads/installer/ and download the community installer. Run it.

B

Select products to install

You need exactly three components. In the product selection screen, add all three to "Products To Be Installed" before proceeding.

C

Configure the server

Install as a Windows Service (so it starts automatically). Set the root password — remember this, you'll need it in Part 2. Optionally create a user account (e.g., username: APP).

D

Verify the installation

Open MySQL Workbench, connect to your local instance, and confirm you can see the query editor. Also check Task Manager → Services tab to confirm MySQL80 shows "Running".

Three Required Components

MySQL ServerThe database engine
MySQL WorkbenchGUI for managing databases
Connector/JJDBC driver for Java apps
Connector/J location: After install, the driver JAR lives at:
C:\Program Files (x86)\MySQL\Connector J 8.0\mysql-connector-java-8.0.29.jar
You'll reference this file when configuring NetBeans database connections.
No environment variables needed for MySQL. The server runs as a Windows Service, and NetBeans connects via JDBC URL.

Part 1 — Step 3

Install NetBeans IDE

A

Download and run the installer

Go to netbeans.apache.org/download/index.html and download the .exe installer for NetBeans 20 or higher. Run it with default settings.

B

Verify the installation

Launch NetBeans. You should see the Start Page with no error messages. If NetBeans cannot find the JDK, it will show an error — this means your JAVA_HOME is not set correctly.

No environment variables needed for NetBeans. It discovers the JDK via your JAVA_HOME setting from Step 1.

Part 1 Completion Checklist

  • java -version shows JDK 21
  • javac -version shows 21.0.x
  • MySQL Workbench connects to local server
  • MySQL80 shows "Running" in Task Manager Services
  • NetBeans opens without errors
Do not proceed to Part 2 until all five checks pass. Environment issues compound — fixing them now saves hours of debugging later.

Part 1

Common Issues & Fixes

If something isn't working, check here before asking for help.

"java" is not recognised as a command

Your PATH variable doesn't include the JDK bin directory. Re-open Environment Variables and make sure %JAVA_HOME%\bin is in PATH. Then open a new terminal — existing terminals don't pick up changes.

MySQL service won't start

Check if another MySQL instance or another program is using port 3306. Open Task Manager → Services and look for conflicting services. You can also try restarting the MySQL80 service manually.

NetBeans can't find JDK

Make sure JAVA_HOME points to the JDK directory (not the JRE). The path should end with \jdk-21, not \jre. You can also configure the JDK path in NetBeans via Tools → Java Platforms.

MySQL Workbench can't connect

Verify MySQL service is running. Check that your root password is correct. If you get "Access denied", reset the password through the MySQL Installer's reconfigure option.

Knowledge Checkpoint

Quiz — Environment Setup

1. Why do we set the JAVA_HOME environment variable?

2. Which MySQL component allows a Java application to connect to the database?

3. After setting PATH, you open a terminal and type java -version but get "not recognised". What's the most likely fix?

2

Your First JPA Project

Building a Java application that persists a Book entity to MySQL using JPA and EclipseLink — no SQL required.

Part 2

What We're Building

A simple Java SE application that creates a Book object in memory and persists it to a MySQL database table using JPA. Here's the full picture of what's involved:

Main.java
Creates a Book, gets EntityManager, persists it
Book.java
Entity class with @Entity, @Id, @Column annotations
persistence.xml
Configures database URL, credentials, provider
MySQL — w1p1db database
MYFAVOURITEBOOK table with the persisted row

Pre-requisites Before Starting

  • JDK 21 installed and verified
  • MySQL server running
  • NetBeans IDE open and working
  • Download EclipseLink 4.0.2+ from eclipse.dev/eclipselink/#download and extract to a folder
EclipseLink is the JPA persistence provider — it's the library that actually implements the JPA specification. JPA is just an API; EclipseLink does the work. Download and extract it before proceeding.

Part 2

Project Structure

Here's the final file structure of the project you're building, so you know where everything goes.

W1P1/ ├── src/ │ ├── META-INF/ │ │ └── persistence.xml │ └── w1p1/ │ ├── Book.java │ └── Main.java ├── Libraries/ │ ├── MySQL Connector/J driver │ ├── EclipseLink 4.0.2 JARs │ └── JDK 21 └── build/

Book.java (Entity)

The JPA entity class annotated with @Entity. Maps to a database table. Contains fields for title, price, description, ISBN, page count, and illustrations.

Main.java (Application)

The entry point. Creates a Book object, obtains an EntityManager, opens a transaction, persists the book, and commits.

persistence.xml (Config)

Tells JPA which database to connect to (JDBC URL, username, password), which provider to use (EclipseLink), and which entity classes to manage.

Part 2 — Steps 1-2

Create the NetBeans Project

1

Create a new Java Application

In NetBeans: File → New Project → Java with Ant → Java Application. Click Next.

2

Set project name and main class

Project Name: W1P1. Tick "Create Main Class" and set it to w1p1.W1P1 (or w1p1.Main). Choose a project location you can find later. Click Finish.

Why "Java with Ant"? This unit uses Ant-based projects because they give you direct control over libraries and build configuration. Maven/Gradle are alternatives you may encounter in industry, but Ant keeps things transparent for learning.

What This Creates

NetBeans generates a project folder with a src/ directory containing your package (w1p1) and a Main.java file with an empty main() method. The Libraries node will initially only contain JDK 21.

Part 2 — Step 3

Create the MySQL Database

Before JPA can connect, the target database must exist. JPA will create the tables for you, but it cannot create the database itself.

3

Open MySQL Workbench and connect to your local instance

Click the connection tile (e.g., "Local instance MySQL80") and enter your root password.

4

Create the database

In the query editor, run the SQL command shown on the right, then click the refresh button in the Schemas panel to confirm w1p1db appears.

This must be done before you configure the database connection in NetBeans (next step). If the database doesn't exist, the connection test will fail.
MySQL Workbench — Query Editor
CREATE DATABASE w1p1db;

Connection Details to Remember

Hostlocalhost
Port3306
Databasew1p1db
UsernameAPP (or root)
PasswordYour MySQL password
JDBC URLjdbc:mysql://localhost:3306/w1p1db

Part 2 — Steps 5-6

Add the Book Entity & Configure JPA

5

Create the Entity Class

Right-click the w1p1 package → New → Entity Class. Set Class Name to Book, Package to w1p1, Primary Key Type to Long. Tick "Create Persistence Unit".

6

Configure the Persistence Unit

On the next screen: Persistence Unit Name: W1P1PU. Persistence Library: EclipseLink (JPA 3.0). Database Connection: select "New Database Connection..."

7

Set up the Database Connection

Driver: MySQL (Connector/J driver). If the driver file isn't found, click Add and browse to the Connector/J JAR. Then fill in host, port, database (w1p1db), username, and password. Click "Test Connection" to verify.

What "Create Persistence Unit" does: It generates a persistence.xml file under META-INF/. This file is the bridge between your Java code and the database — it tells JPA where the database is and how to connect.
EclipseLink libraries: Make sure all EclipseLink JARs (from the jlib/ folder of your extracted EclipseLink download) are added to the project's Libraries. Without them, the project won't compile.

Required Libraries

Your Libraries node should contain:

MySQL Connector/J driver
All EclipseLink 4.0.2 JARs (eclipselink.jar, jakarta.persistence-api, jakarta.annotation-api, etc.)
JDK 21

Part 2 — Source Code

Book.java — The Entity Class

Replace the generated Book.java content with this code. Each annotation tells JPA how to map this class to the database.

package w1p1; import jakarta.persistence.*; @Entity @Table(name = "MyFavouriteBook") public class Book { // Attributes @Id @GeneratedValue(strategy = GenerationType.AUTO) private Long id; @Column(name = "Book_TiTle", nullable = false, updatable = false) private String title; private Float price; @Column(length = 2000) private String description; private String isbn; @Column(name = "Number_of_Pages", nullable = false) private Integer nbOfPage; private Boolean illustrations; // Constructors public Book() { } public Book(Long id, String title, Float price, String description, String isbn, Integer nbOfPage, Boolean illustrations) { this.id = id; this.title = title; this.price = price; this.description = description; this.isbn = isbn; this.nbOfPage = nbOfPage; this.illustrations = illustrations; } // Getters and Setters for all fields // ... (generate via NetBeans: right-click → Insert Code → Getter and Setter) @Override public String toString() { return "Book{id=" + id + ", title='" + title + "', price=" + price + ", isbn='" + isbn + "', nbOfPage=" + nbOfPage + ", illustrations=" + illustrations + "}"; } }

Annotation Breakdown

@EntityMarks this class for JPA management
@TableOverrides the default table name
@IdMarks the primary key field
@GeneratedValueAuto-generates the ID value
@ColumnCustomises column name, constraints, length
Configuration by exception: Fields without @Column (like price, isbn) still map — JPA uses the field name as the column name by default. You only annotate when you want to customise.
Generate getters/setters: In NetBeans, right-click inside the class → Insert Code → Getter and Setter → select all fields. This saves you writing boilerplate.

Part 2 — Source Code

Main.java — The Application

This is the entry point that creates a Book and persists it to the database.

package w1p1; import jakarta.persistence.EntityManager; import jakarta.persistence.EntityManagerFactory; import jakarta.persistence.EntityTransaction; import jakarta.persistence.Persistence; public class Main { public static void main(String[] args) { // 1. Create an instance of Book Book book = new Book(); book.setTitle("The Hitchhiker's Guide to the Galaxy"); book.setPrice(12.5f); book.setDescription("Science fiction comedy series " + "created by Douglas Adams."); book.setIsbn("1-84023-742-2"); book.setNbOfPage(354); book.setIllustrations(false); // 2. Get an EntityManager from the factory EntityManagerFactory emf = Persistence.createEntityManagerFactory("W1P1PU"); EntityManager em = emf.createEntityManager(); // 3. Persist the book inside a transaction EntityTransaction tx = em.getTransaction(); tx.begin(); em.persist(book); tx.commit(); System.out.println("**** Persist the book ****"); System.out.println(book); } }

Line-by-Line Breakdown

Step 1: Create a Book POJO and populate its fields. At this point it's just a regular Java object — JPA doesn't know about it (it's in the "New" lifecycle state).

Step 2: createEntityManagerFactory("W1P1PU") reads persistence.xml, finds the persistence unit named "W1P1PU", and sets up the database connection.

Step 3: em.persist(book) tells JPA to manage this object. When tx.commit() runs, JPA generates an INSERT SQL statement and executes it against MySQL. The book is now in the database.

The string "W1P1PU" must exactly match the persistence unit name defined in persistence.xml. A mismatch here is one of the most common errors.

Part 2 — Source Code

persistence.xml — The Configuration

This file lives in src/META-INF/persistence.xml and tells JPA everything it needs to connect to the database.

<?xml version="1.0" encoding="UTF-8"?> <persistence version="2.1" xmlns="http://xmlns.jcp.org/xml/ns/persistence"> <persistence-unit name="W1P1PU" transaction-type="RESOURCE_LOCAL"> <provider> org.eclipse.persistence.jpa.PersistenceProvider </provider> <class>w1p1.Book</class> <properties> <property name="jakarta.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/w1p1db"/> <property name="jakarta.persistence.jdbc.user" value="APP"/> <property name="jakarta.persistence.jdbc.driver" value="com.mysql.cj.jdbc.Driver"/> <property name="jakarta.persistence.jdbc.password" value="APP"/> <property name="jakarta.persistence.schema-generation.database.action" value="create"/> </properties> </persistence-unit> </persistence>

Property Breakdown

jdbc.urlWhere the database is (host, port, database name)
jdbc.userMySQL username
jdbc.passwordMySQL password
jdbc.driverThe JDBC driver class (from Connector/J)
schema-generationcreate = auto-create tables on first run
Update these values to match your MySQL installation. If your username is root and your password is mypassword, change them here — not in Main.java.
RESOURCE_LOCAL means we manage transactions ourselves in code (tx.begin() / tx.commit()). In Week 5+, we'll use container-managed transactions (JTA) where the server handles this for you.

Part 2 — Steps 9-11

Build, Run, and Verify

9

Build the project

Right-click the project → Clean and Build. The Output window should show "BUILD SUCCESSFUL". If you get errors, check that all libraries are added and the code compiles cleanly.

10

Run the application

Right-click the project → Run. In the Output window, you should see the EclipseLink banner followed by your Book's toString() output with a generated ID.

11

Verify in the database

Open MySQL Workbench, select the w1p1db schema, and run the query shown on the right. You should see one row with the book data.

Expected console output:
**** Persist the book ****
Book{id=551, title='The Hitchhiker's Guide to the Galaxy', price=12.5, isbn='1-84023-742-2', nbOfPage=354, illustrations=false}
MySQL Workbench — Verify
SELECT * FROM w1p1db.myfavouritebook;

Expected Table Contents

IDBOOK_TITLEPRICEISBN
551The Hitchhiker's Guide...12.51-84023-742-2

The ID value will vary — it's auto-generated.

You can also verify from NetBeans: go to the Services tab → Databases → expand your w1p1db connection → Tables → myfavouritebook → right-click → View Data.

Part 2

Common Issues & Fixes

If the build or run fails, check these common problems first.

"No Persistence provider for EntityManager"

EclipseLink JARs are not in the project Libraries. Add all JARs from the EclipseLink jlib/ folder.

"Unknown database 'w1p1db'"

You forgot to create the database in MySQL Workbench. Run CREATE DATABASE w1p1db; first.

"Access denied for user 'APP'@'localhost'"

The username or password in persistence.xml doesn't match your MySQL credentials. Update the jdbc.user and jdbc.password properties.

"Table 'myfavouritebook' already exists" on re-run

The schema-generation action is set to create, which tries to create the table each run. Change it to drop-and-create during development, or none after the first run.

"ClassNotFoundException: com.mysql.cj.jdbc.Driver"

The MySQL Connector/J JAR is not in the project Libraries. Add the mysql-connector-java-8.x.x.jar file from your MySQL Connector installation folder.

Build succeeds but nothing appears in the database

Check that tx.commit() is called after em.persist(book). Without the commit, the transaction is rolled back and nothing is written.

Knowledge Checkpoint

Quiz — First JPA Project

4. What is the purpose of persistence.xml?

5. What happens if you call em.persist(book) but never call tx.commit()?

6. In persistence.xml, what does schema-generation.database.action = "create" do?

Extension

Challenge Tasks (Optional)

Finished early? Try these exercises to deepen your understanding. Each one builds on what you've already done.

Beginner

Persist multiple books

Modify Main.java to create and persist three different books in a single transaction. Verify all three appear in the database table.

Intermediate

Add a query

After persisting the books, use em.find(Book.class, id) to retrieve one by its ID and print it. Then try a JPQL query: em.createQuery("SELECT b FROM Book b", Book.class).getResultList() to retrieve all books.

Advanced

Add a second entity

Create an Author entity class with fields for name and biography. Add it to persistence.xml as a second <class> entry. Persist an Author and verify the new table appears in MySQL.

Looking ahead: In Week 2, you'll learn about entity relationships — linking Book and Author entities together with @ManyToOne and @OneToMany annotations. The extension tasks here give you a head start.
End of Week 1 Lab

Lab Complete

You now have a working Jakarta EE development environment and a running JPA application that persists data to MySQL.

If you had any issues, note them down and bring your questions to the next session.
The complete sample project is available on the Week 1 block of the unit Moodle site.