In this article, we are going to learn how to create a REST API using Java EE 8, MicroProfile, Hibernate, PostgreSQL and the TomEE application server. It’s really easy and fun to develop Java EE 8 applications.
Tools You Will Need:
- Maven 3.3+
- JDK 1.8
- PostgreSQL
Note: We will not go through the process of how to install the needed tools in this tutorial.
Generate the Project
We will use the MicroProfile starter to generate our application. Go to start.microprofile.io and enter the details as follows:
groupId: org.superbiz artifactId: blog MicroProfile Version: 2.0.1 MicroProfile Server: Apache TomEE 8.0.0-M2 Examples for specifications: Uncheck all examples
Open pom.xml and add the following dependencies to the <dependencies> section:
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-api</artifactId>
<version>8.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-agroal</artifactId>
<version>5.4.3.Final</version>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>42.2.5</version>
</dependency>
We added Java EE 8, Hibernate and PostgreSQL dependencies. In the <properties> section find the TomEE version and update it to 8.0.0-M3 and while we are at it change the tomeeClassifier to plus instead of microprofile.
TomEE Config
It’s time to start the real coding, the first thing we will do is to configure the DataSource. Create the resources.xml file inside src/main/webapp/WEB-INF/ and make it look like this:
<?xml version="1.0" encoding="UTF-8"?>
<tomee>
<Resource id="jdbc/my_blog_datasource" type="javax.sql.DataSource">
JdbcDriver = org.postgresql.Driver
JdbcUrl = jdbc:postgresql://localhost/blog
UserName = mybloguser
Password = mypass
jtaManaged = true
</Resource>
</tomee>
This is the configuration for the database connection. Now create the persistence.xml inside src/main/resources/META-INF/ and make it look like this:
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="1.0"
xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd">
<persistence-unit name="myBlog_PU" transaction-type="JTA">
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
<jta-data-source>jdbc/my_blog_datasource</jta-data-source>
<exclude-unlisted-classes>false</exclude-unlisted-classes>
<properties>
<property name="tomee.jpa.factory.lazy" value="true" />
<property name="hibernate.dialect" value="org.hibernate.dialect.PostgreSQL10Dialect" />
<property name="hibernate.show_sql" value="false" />
<property name="hibernate.format_sql" value="true" />
<property name="hibernate.transaction.jta.platform" value="org.hibernate.service.jta.platform.internal.SunOneJtaPlatform"/>
</properties>
</persistence-unit>
</persistence>
The persistence.xml is the standard configuration file for JPA and it has to be included in the META-INF directory.
The persistence.xml file defines what provider to be used, the name of the persistence unit, and how classes should be mapped to database tables.
We are done with the configurations and it’s time to start coding our API.
Creating Entities
Entities are POJOs (Plain Old Java Objects) class which are annotated so it can be easily persisted.
Create a new file called Post.java inside entities package and add the following:
package org.superbiz.blog.entities;
import javax.persistence.*;
import javax.validation.constraints.Size;
import java.io.Serializable;
import java.util.Date;
@Entity
@Table(name = "posts")
@NamedQueries({
@NamedQuery(name = "Post.findAll", query = "SELECT p FROM Post p")
})
public class Post implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@Column(name = "title", length = 255)
private String title;
@Column(name = "body", length = 1000)
@Size(min=10, max=1000)
private String body;
private Date createdAt;
private Date updatedAt;
private String author;
public static long getSerialVersionUID() {
return serialVersionUID;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getBody() {
return body;
}
public void setBody(String body) {
this.body = body;
}
public Date getCreatedAt() {
return createdAt;
}
public void setCreatedAt(Date createdAt) {
this.createdAt = createdAt;
}
public Date getUpdatedAt() {
return updatedAt;
}
public void setUpdatedAt(Date updatedAt) {
this.updatedAt = updatedAt;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
@PrePersist
private void onCreate() {
createdAt = new Date();
}
@PreUpdate
private void onUpdate() {
updatedAt = new Date();
}
}
@Entityannotation indicates that it is a JPA entity.@Tableannotation is used to name the table in the database.@NamedQueriesannotation is used to add multiple queries.@NamedQueryannotation defines query with a name.@Idannotation is used to define the primary key and theIdproperty is also annotated with@GeneratedValueto indicate that theIdshould be generated automatically.@Sizeannotation is a bean validation that validates that the value is between the attributeminandmax.@Columnannotation is used to specify the mapped column for a persistent property.
Business Logic
Create a new file called PostRepository inside repositories package and add the following:
package org.superbiz.blog.repositories;
import org.superbiz.blog.entities.Post;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import java.util.List;
@Stateless
public class PostRepository {
@PersistenceContext(unitName = "myBlog_PU")
EntityManager em;
public List getAllPosts() {
return em.createNamedQuery("Post.findAll", Post.class).getResultList();
}
public Post findById(Long id) {
return em.find(Post.class, id);
}
public void create(Post post) {
em.persist(post);
}
public void update(Post post) {
em.merge(post);
}
public void delete(Post post) {
if (!em.contains(post)) {
post = em.merge(post);
}
em.remove(post);
}
}
@PersistenceContextannotation injects theEntityManagerto be used at runtime.getAll()method retrieves all the posts from the database and return the entire list.findById()method finds onePostobject from the database with ID and returns it.update()method will update existingPostobject in the database.create()method will createPostobject in the database.delete()method will find thePostbject in the database and delete it.
Resource
The next step is to create a resource class. Create a new file called PostResource.java inside resources package and move the BlogRestApplication.java inside that package also and remove the HelloController.java because we don’t need that.
package org.superbiz.blog.resources;
import org.superbiz.blog.entities.Post;
import org.superbiz.blog.repositories.PostRepository;
import javax.enterprise.context.RequestScoped;
import javax.inject.Inject;
import javax.ws.rs.*;
import javax.ws.rs.core.*;
@RequestScoped
@Path("posts")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public class PostResource {
@Inject
PostRepository postRepository;
@GET
public Response getAllPosts() {
return Response.ok().entity(postRepository.getAllPosts()).build();
}
@GET
@Path("{id}")
public Response getPostById(@PathParam("id") Long id) {
return Response.ok().entity(postRepository.findById(id)).build();
}
@POST
public Response create(Post post, @Context UriInfo uriInfo) {
Post postId = postRepository.create(post);
UriBuilder builder = uriInfo.getAbsolutePathBuilder();
builder.path(Long.toString(postId.getId()));
return Response.created(builder.build()).build();
}
@PUT
@Path("{id}")
public Response update(@PathParam("id") Long id, Post post) {
Post updatePost = postRepository.findById(id);
updatePost.setTitle(post.getTitle());
updatePost.setBody(post.getBody());
updatePost.setAuthor(post.getAuthor());
return Response.ok().entity(post).build();
}
@DELETE
@Path("{id}")
public Response delete(@PathParam("{id}") Long id) {
Post post = postRepository.findById(id);
postRepository.delete(post);
return Response.noContent().build();
}
}
@RequestScopedannotation indicates that this class will be created once every request.@Pathannotation identifies the URI path to which the resource responds.@Producesannotation will automatically convert the response to JSON format.@Consumesannotation will automatically convert the posted JSON string here intoPostobject.- We inject the
PostRepositorywith the@Injectannotation. @GETannotation maps/postsHTTP GET request togetAll()method, which will retrieve all the posts from the database and return the entire list.- Parameters are accessed with the
@PathParamannotation. @PUTannotation is for handling HTTP PUT request and it is meant to update an existing resource.@POSTannotation is for handling HTTP POST request and it is meant to create a new resource.@DELETEannotation is for handling HTTP DELETE request.
Your directory structure should look like this:
$ tree
.
├── pom.xml
├── readme.md
└── src
├── main
│ ├── java
│ │ └── org
│ │ └── superbiz
│ │ └── blog
│ │ ├── entities
│ │ │ └── Post.java
│ │ ├── repositories
│ │ │ └── PostRepository.java
│ │ └── resources
│ │ ├── BlogRestApplication.java
│ │ └── PostResource.java
│ ├── resources
│ │ ├── META-INF
│ │ │ ├── microprofile-config.properties
│ │ │ └── persistence.xml
│ │ └── publicKey.pem
│ └── webapp
│ ├── WEB-INF
│ │ ├── beans.xml
│ │ └── resources.xml
│ └── index.html
└── test
└── java
Test
Time to test our application. Open your terminal and navigate to the directory where you have the application and run the following command to build and start the TomEE application server:
$ mvn clean package && java -jar target/blog-exec.jar
Open a new terminal window and use curl to test that everything works.
GET Request
$ curl -v http://localhost:8080/data/posts
Single GET Request
$ curl -v http://localhost:8080/data/posts/3
POST Request
$ curl --header "Content-Type: application/json" \
--request POST \
--data '{"title":"My First Blog Post","body":"Welcome to my first blog post, this blog runs on TomEE Application Server",
"author": "Hayri Cicek"}' \
http://localhost:8080/data/posts
PUT Request
$ curl -X PUT -H "Content-Type: application/json" -d '{"title":"My Updated Blog Post","body":"Welcome to my Updated blog post, this blog runs on TomEE Application Server", "author": "Hayri Cicek"}' http://localhost:8080/data/posts/3
DELETE Request
$ curl -X "DELETE" http://localhost:8080/data/posts/3
As you can see, it’s really easy and fun to create REST API’s with Java EE 8 and running on TomEE Application Server.




Nice guide!
Hi,
Thanks for the great article.
I have some similar kind of requirement, please guide me is it possible or not and if possible please suggest how to achieve this.
I have created a spring boot project with JPA which running in TomEE with multiple databases( https://github.com/deepeshuniyal/JNDISpringBootTom8.git ), which is working fine.
Now I have to use TomEE JTA with multiple databases. commit will work with multiple databases in groups.
Hoping for your response.
Hi Deepesh,
Base on the context you provided, it seems like your scenario will require XA data sources [1] since you want to have two-phase commits with multiple databases.
We also invite you to join the TomEE community [2] to have a broader conversation.
[1] https://tomee.apache.org/tomee-8.0/docs/configuring-datasources-xa.html
[2] https://tomee.apache.org/community/contributing/contribution-tips.html