HelloWorld JPA application

Welcome to our JPA hello world tutorial, where we’ll guide you through the basics of Java Persistence API (JPA).  Follow along as we demonstrate step-by-step instructions, best practices, and practical examples to ensure you grasp the fundamental concepts of JPA programming. Let’s dive into this comprehensive tutorial and unlock the power of JPA for your next project.

Create the Maven project

Firstly, we need a Maven project for our HelloWorld JPA application. We recommend using the Jakarta EE Starter which allows to generate a Maven project for Jakarta EE 8/9/10 Projects: https://start.jakarta.ee/

Select the Jakarta EE version, the Java version and the Runtime, for example WildFly application Server:

jpa hello world tutorial

Coding the Entity Class

Firstly, let’s define our Model. We will be using a single Customer Class to map a Database Table.

jpa example wildfly

Here is our Customer Class definition:

public class Customer implements Serializable {

    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String name;
    private String email;
    private String address;

    @Column(name = "phone_number")
    private String phoneNumber;

    // Getter/Setter methods omitted for brevity

To learn more about different types of Strategies you can use for Primary Keys check this article: Choosing the Strategy for Primary keys in JPA

Coding the Service Class

Next, in order to store our Entity in a transactional way, we a CDI Bean which uses Transactional methods in insert and update operations:

public class CustomerService {
    private static final Logger LOGGER = Logger.getLogger(CustomerService.class.getName());

    EntityManager em;

    public void createCustomer(Customer customer) {
        LOGGER.info("Created Customer "+customer);


    public void updateCustomer( Customer customer ) {
        Customer customerToUpdate = findCustomerById(customer.getId());

        LOGGER.info("Updated customer" + customer);

    public void deleteCustomer(Long customerId) {
        Customer c = findCustomerById(customerId);
        LOGGER.info("Deleted Customer with id" + customerId);

    public Customer findCustomerById(Long id) {
        Customer customer = em.find(Customer.class, id);
        if (customer == null) {
            throw new WebApplicationException("Customer with id of " + id + " does not exist.", 404);
        return customer;

    public List<Customer> findAllCustomers() {
        Query query = em.createQuery("SELECT c FROM Customer c");
        List<Customer> customerList = query.getResultList();
        return customerList;

    public Customer findCustomerByName(String name) {
        Query query = em
                .createQuery("SELECT c FROM Customer c WHERE c.name = :name");
        query.setParameter("name", name);
        Customer customer = (Customer) query.getSingleResult();
        return customer;


Coding a REST Endpoint for the Service Class

Finally, we need a front-end for our application. To keep it pretty simple, we will add a basic REST Endpoint which maps all the Service methods:


public class CustomerEndpoint {

    CustomerService customerService;

    public Response create(Customer customer) {
        return Response.status(201).build();

    public List<Customer> findAllCustomers() {
        return customerService.findAllCustomers();

    public Customer findCustomerById(@PathParam("id") Long id) {
        return customerService.findCustomerById(id);

    public Response updateCustomer(Customer customer) {
        return Response.status(204).build();
    public Response delete(@PathParam("id") Long id) {
        return Response.status(204).build();


As you can see, the above REST endpoint has some basic methods for creating and querying our Entity objects, returning a JSON view of it. In order to get it working our REST Services, we need a REST Activator class:

public class RestActivator extends Application {

Adding the persistence.xml file

Then, we will add a persistence.xml file which binds the Persistence Unit to the default ExampleDS Datasource that is available in WIldFly.

<persistence xmlns="https://jakarta.ee/xml/ns/persistence"
             xsi:schemaLocation="https://jakarta.ee/xml/ns/persistence https://jakarta.ee/xml/ns/persistence/persistence_3_1.xsd"
    <persistence-unit name="primary">

            <property name="jakarta.persistence.schema-generation.database.action"
            <property name="jakarta.persistence.schema-generation.create-source"
            <property name="jakarta.persistence.schema-generation.drop-source"

            <property name="hibernate.show_sql" value="true"/>


As you can see from the above configuration, we are also adding the properties to allow the generation of the Database schema from the annotations available in the application.

Some sample Data with import.sql

Finally, we will add a resources/import.sql file to insert some sample data at start:

INSERT INTO Customer (name, email, address, phone_number) VALUES ('John Doe', '[email protected]', '123 Main Street', '555-1234')
INSERT INTO Customer (name, email, address, phone_number) VALUES ('Jane Smith', '[email protected]','45 Elm Street','34243')

Run and Test the Project

Now compile the project:

$ mvn clean install wildfly:deploy

Then, let’s list all available Customers:

curl -s -X GET http://localhost:8080/jpa-basic/rest/customer | jq
    "address": "123 Main Street",
    "email": "[email protected]",
    "id": 1,
    "name": "John Doe",
    "phoneNumber": "555-1234"
    "address": "45 Elm Street",
    "email": "[email protected]",
    "id": 2,
    "name": "Jane Smith",
    "phoneNumber": "34243"

To add a new Customer:

curl -X POST -H "Content-Type: application/json" -d '{
  "name": "Frank Smith",
  "email": "[email protected]",
  "address": "123 Random Street",
  "phoneNumber": "432-1234"
}' http://localhost:8080/jpa-basic/rest/customer

To update an existing Customer:

curl -X PUT -H "Content-Type: application/json" -d '{
  "id": {id},
  "name": "Updated Name",
  "email": "[email protected]",
  "address": "456 Elm Street",
  "phoneNumber": "555-5678"
}' http://localhost:8080/jpa-basic/rest/customer

Finally, to delete a Customer:

curl -X DELETE http://localhost:8080/jpa-basic/rest/customer/{id}


Congratulations on completing this JPA hello world tutorial! You have gained a solid understanding of Java Persistence API and its capabilities for simplifying database operations and improving code maintainability. By following along with our step-by-step instructions and practical examples, you have taken the first step towards becoming proficient in JPA programming. Armed with this knowledge, you can now confidently incorporate JPA into your projects, unlocking its power to streamline data persistence and manipulation. Keep exploring and experimenting with JPA’s advanced features to take your data management to the next level. Happy coding with JPA!

You can find the source code for this JPA application on: https://github.com/fmarchioni/mastertheboss/tree/master/javaee/jpa-basic