Giter VIP home page Giter VIP logo

draft-guide-jpa-intro's Introduction

Accessing and persisting data in microservices

Note
This repository contains the guide documentation source. To view the guide in published form, view it on the Open Liberty website.

Learn how to use Java Persistence API to access and persist data to a database for your microservices.

What you’ll learn

You will learn how to use the Java Persistence API (JPA) to map Java objects to relational database tables and perform create, read, update and delete (CRUD) operations on the data in your microservices.

JPA is a Java specification for representing relational database table data as Plain Old Java Objects (POJO). JPA simplifies object-relational mapping (ORM) by using annotations to map Java objects to tables in a relational database. In addition to providing an efficient API for performing CRUD operations, JPA also reduces the burden of having to write JDBC and SQL code when performing database operations and takes care of database vendor specific differences. This allows you to focus on the business logic of your application instead of wasting time implementing repetitive CRUD logic.

The application that you will be working with is an event manager, which is composed of a UI and an event microservice for creating, retrieving, updating, and deleting events. The application uses an Embedded Derby database as a datastore for all the events.

You will use JPA annotations to define an entity class whose fields are persisted to the database. The interaction between your application and the database is mediated by the persistence context that is managed by an EntityManager. The EntityManager can be application-managed or container-managed. In this guide you will be using a container-managed EntityManager, placing the burden of managing the lifecycle of the EntityManager on the application server. The lifecycle of the persistence context can either be transaction-scoped or extended when using a container-managed EntityManager. You will be focused on using a container-managed EntityManager with a transaction-scoped persistence context to take advantage of the application server’s services.

Point your browser to the http://localhost:9080/eventmanager.jsf URL. The event application currently has no events stored in the database. Go ahead and click on the Create Event button located in the left navigation bar. After entering an event name, location and time, click on Submit to persist your event entity to the database. The event is now stored in the database and is visible in the list of current events.

Notice that if you stop the Open Liberty server:

mvn liberty:stop-server

and then restart it:

mvn liberty:start-server

The events created are still displayed in the list of current events. The Update button located beside each event allows you to make modifications to the persisted entity and the Delete button allows you to remove entities from the database.

Defining a JPA entity class

Navigate to the start directory to begin.

To store Java objects in a database, you must define a JPA entity class. A JPA entity is a Java object whose non-transient and non-static fields will be persisted to the database. Any Plain Old Java Object (POJO) class can be designated as a JPA entity. However, the class must be annotated with the @Entity annotation, must not be declared final and must have a public or protected non-argument constructor. JPA maps an entity type to a database table and persisted instances will be represented as rows in the table.

The Event class is a model that represents events in the application and is annotated with JPA annotations. Create the Event class in the src/main/java/io/openliberty/guides/models/Event.java file:

link:finish/src/main/java/io/openliberty/guides/models/Event.java[role=include]

Let’s break down the new annotations that are used in this JPA entity class:

Annotation Description

@Entity

Declares the class as an entity

@Table

Specifies details of the table such as name

@NamedQuery

Specfies a predefined database query that can be executed by the EntityManager at runtime

@Id

Declares the pimary key of the entity

@GeneratedValue

Specifies the generation strategy for the value of the primary key. strategy = GenerationType.AUTO indicates that a generation strategy will be chosen based on the database being used

@Column

Specifies that the field is mapped to a column in the database table, name is optional and indicates the name of the column in the table

Configuring the EntityManager

An EntityManager provides the functionality to perform operations on the database such as persisting new entities, fetching entities through the find() method and queries, updating changes, and removing entities.

The EntityManager manages the lifecycle of entity instances. Every EntityManager instance is associated with a persistence context. The persistence context manages a set of entities and is aware of the different states that an entity can have. The configuration information of the EntityManager, such as the transaction type and datastore, is also defined by the persistence unit specified in the persistence.xml file.

Create the src/main/resources/META-INF/persistence.xml file:

link:finish/src/main/resources/META-INF/persistence.xml[role=include]

The persistence unit is defined by the <persistence-unit> XML element. The name attribute is required and is used to identify the persistent unit. The transaction-type=”JTA” element specifies that the persistence context will enlist with Java Transaction API (JTA) global transactions. Since we are using a container-managed EntityManager, it is required that JTA transactions are used.

The eclipselink.ddl-generation properties are used here to avoid having to manually create a database table to run this sample application. To learn more about the ddl-generation properties, see the JPA Extensions Reference for EclipseLink.

A JTA transaction type requires a data source to be provided. This is done through the eventjpadatasource element which specifies the Java Naming and Directory Interface (JNDI) name of the data source that is to be used.

The Java Database Connectivity (JDBC) connection is specified in the data source which is configured in the server.xml file. Create the src/main/liberty/config/server.xml file:

link:finish/src/main/liberty/config/server.xml[role=include]

The derbyJDBCLib element is a shared library that points to the directory of the JDBC driver. The JDBC driver is what enables the application to interact with the database.

The data source configuration is done within the <dataSource> element. The <properties.derby.embedded> attribute within the data source configuration contains embedded derby properties such as the database name and whether to create the database if it does not already exist.

Performing CRUD operations using JPA

Every entity object has a lifecycle that consists of four states: new, managed, detached and removed. Whenever a new Event object is created its state will be new, meaning that it is not mapped to a row in the database table and is not associated with an EntityManger. Managed entities are actively tracked by the persistence context. Entities become managed when they are persisted, merged, or fetched by find() or a query. Detached entities are no longer managed by a persistence context. Entities become detached when the EntityManager is cleared, closed or explicitly detached. When using a container-managed EntityManager, entities automatically become detached at the end of transaction boundaries. Lastly, removed entities will be marked for removal and will be deleted from the database upon transaction commit.

To perform CRUD operations using JPA, create the src/main/java/io/openliberty/guides/dao/EventDao.java file:

link:finish/src/main/java/io/openliberty/guides/dao/EventDao.java[role=include]

The EventDao class can then be injected into other components of your application. Notice how it is injected into the src/main/java/io/openliberty/resources/EventService.java file to provide the EventService class with a way to persist and access data.

In order to use the EntityManager at runtime, it must be injected into our CDI bean through the @PersistenceContext annotation. The @Transactional annotation allows the application to manage transaction boundaries on CDI managed beans. This ensures that the required methods are executed within the boundaries of an active global transaction, which is why it is not necessary to explicitly begin, commit or rollback transactions.

Since we are using a transaction-scoped persistence context, a new persistence context will begin when the EntityManager is invoked within an active transaction and will end when the transaction commits or rolls back. At the end of the transactional method invocation, the persistence context will be notified that the transaction is committing, and will flush any changes made to entity instances it is managing to the database. The managed entities will then become detached.

The EventDao.java class has a method for each CRUD operation, so let’s break them down:

  • The createEvent() method persists an instance of the Event entity class to the datastore by calling the persist() method on an EntityManager instance. The event objects state will be changed from new to managed and changes to it are now tracked by the EntityManager.

  • The readEvent() method will return an instance of the Event entity class with the specified primary key by calling the find() method on an EntityManager instance. If the event instance is found, it will be returned in a managed state, but, if the event instance is not found, Null will be returned.

  • The readAllEvents() method demonstrates an alternate way to retrieve event objects from the database. This method returns a list of instances of the Event entity class using a query specified in the @NamedQuery annotation on the Event class. The event instances will be returned in a managed state.

  • The updateEvent() method creates a managed instance of a detached entity object. The EntityManager automatically tracks all managed entity objects in its persistence context for changes and synchronizes them with the database. But, if an entity becomes detached, you must merge that entity into the persistence context by calling the merge() method on an EntityManager instance in order for changes to the detached entity’s loaded fields to be tracked.

  • The deleteEvent() method removes an instance of the Event entity class from the database by calling the remove() method on an EntityManager instance. The managed entity gets removed from the database and its state becomes removed.

When the server is running, visit the http://localhost:9080/eventmanager.jsf URL to view the Event Manager application.

Using the Create event button in the left navigation bar you are able to create events that will be persisted to the database. Once you have created an event, it will be available to view, update, and delete in the Event list section.

Testing the application

Create the EventEntityTest test class in the src/test/java/it/io/openliberty/guides/event/EventEntityTest.java file:

link:finish/src/test/java/it/io/openliberty/guides/event/EventEntityTest.java[role=include]

The testCRUD() method creates a test event and persists it to the database. The event object is then retrieved from the database to verify that the test event was actually persisted. Next, the test event’s name, location, and time is updated. The event object is retrieved from the database to verify that the updated event is stored. Finally, the updated test event is deleted and one final check is done to ensure the updated test event is no longer stored in the database.

-------------------------------------------------------
 T E S T S
-------------------------------------------------------
Running it.io.openliberty.guides.jpaguide.tests.EventEntityTest
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 5.9 sec - in it.io.openliberty.guides.jpaguide.tests.EventEntityTest

Results :

Tests run: 1, Failures: 0, Errors: 0, Skipped: 0

Great work! You’re done!

You have learned how to map Java objects to database tables by defining a JPA entity class whose instances are represented as rows in the table.

You have have learned how to configure an EntityManager and use container-managed transactions to perform basic CRUD operations on a database using JPA.

draft-guide-jpa-intro's People

Contributors

ahmad-ayyoub avatar andrewdes avatar dazey3 avatar evelinec avatar justineechen avatar proubatsis avatar

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.