Build a Java application
The following tutorial implements a REST API server using the Java Ebeans ORM. The scenario is that of an e-commerce application where database access is managed using the Play framework; Play uses Akka internally and exposes Akka Streams and actors in Websockets and other streaming HTTP responses. It includes the following tables:
users
— the users of the e-commerce siteproducts
— the products being soldorders
— the orders placed by the usersorderline
— each line item of an order
The source for the above application can be found in the Using ORMs with YugabyteDB repository.
Prerequisites
This tutorial assumes that you have:
- YugabyteDB up and running. If you are new to YugabyteDB, follow the steps in Quick start to have YugabyteDB up and running in minutes.
- Java Development Kit (JDK) 1.8 is installed. JDK installers for Linux and macOS can be downloaded from OpenJDK, AdoptOpenJDK, or Azul Systems. Homebrew users on macOS can install using
brew install AdoptOpenJDK/openjdk/adoptopenjdk8
. - sbt is installed.
Clone the "orm-examples" repository
$ git clone https://github.com/yugabyte/orm-examples.git && cd orm-examples/java/ebeans
Database configuration
-
Modify the database configuration section of the
conf/application.conf
file to include the YugabyteDB JDBC driver settings as follows:#Default database configuration using PostgreSQL database engine default.username=yugabyte default.password="" default.driver=com.yugabyte.Driver default.url="jdbc:yugabytedb://127.0.0.1:5433/ysql_ebeans?load-balance=true"
-
Add a dependency in
build.sbt
for the YugabyteDB JDBC driver.libraryDependencies += "com.yugabyte" % "jdbc-yugabytedb" % "42.3.0"
-
From your local YugabyteDB installation directory, connect to the YSQL shell using:
$ ./bin/ysqlsh
ysqlsh (11.2) Type "help" for help. yugabyte=#
-
Create the
ysql_ebeans
database using:yugabyte=# CREATE DATABASE ysql_ebeans;
-
Connect to the database using:
yugabyte=# \c ysql_ebeans;
Build the application
Create a build.properties
file under the project
directory and add the sbt version.
sbt.version=1.2.8
Build the REST API server from the ebeans
directory using:
$ sbt compile
Note
- Some subversions of JDK 1.8 require the
nashorn
package. If you get a compile error due to a missingjdk.nashorn
package, add the dependency to thebuild.sbt
file.
libraryDependencies += "com.xenoamess" % "nashorn" % "jdk8u265-b01-x3"
- To change the default port (8080) for the REST API Server, set the
PlayKeys.playDefaultPort
value in thebuild.sbt
file.
Run the application
Run the application from the ebeans
directory using:
$ sbt run
Send requests to the application
Create 2 users.
$ curl --data '{ "firstName" : "John", "lastName" : "Smith", "email" : "jsmith@example.com" }' \
-v -X POST -H 'Content-Type:application/json' http://localhost:8080/users
$ curl --data '{ "firstName" : "Tom", "lastName" : "Stewart", "email" : "tstewart@example.com" }' \
-v -X POST -H 'Content-Type:application/json' http://localhost:8080/users
Create 2 products.
$ curl \
--data '{ "productName": "Notebook", "description": "200 page notebook", "price": 7.50 }' \
-v -X POST -H 'Content-Type:application/json' http://localhost:8080/products
$ curl \
--data '{ "productName": "Pencil", "description": "Mechanical pencil", "price": 2.50 }' \
-v -X POST -H 'Content-Type:application/json' http://localhost:8080/products
In your YSQL shell, verify the userId
and productId
from the ysql_ebeans
database using the following YSQL commands.
ysql_ebeans=# select * from users;
user_id | first_name | last_name | user_email
---------+------------+-----------+----------------------
1 | John | Smith | jsmith@example.com
101 | Tom | Stewart | tstewart@example.com
(2 rows)
ysql_ebeans=# select * from products;
product_id | description | price | product_name
------------+-------------------+-------+--------------
1 | 200 page notebook | 7.50 | Notebook
2 | Mechanical pencil | 2.50 | Pencil
(2 rows)
Create 2 orders using the userId
for John.
$ curl \
--data '{ "userId": "1", "products": [ { "productId": 1, "units": 2 } ] }' \
-v -X POST -H 'Content-Type:application/json' http://localhost:8080/orders
$ curl \
--data '{ "userId": "1", "products": [ { "productId": 1, "units": 2 }, { "productId": 2, "units": 4 } ] }' \
-v -X POST -H 'Content-Type:application/json' http://localhost:8080/orders
Query results
Using the YSQL shell
In your YSQL shell, list the tables created by the application.
ysql_ebeans=# \d
List of relations
Schema | Name | Type | Owner
--------+-------------------------+----------+----------
public | orderline | table | yugabyte
public | orders | table | yugabyte
public | orders_user_id_seq | sequence | yugabyte
public | products | table | yugabyte
public | products_product_id_seq | sequence | yugabyte
public | users | table | yugabyte
public | users_user_id_seq | sequence | yugabyte
(7 rows)
Note the 4 tables and 3 sequences in the list above.
ysql_ebeans=# SELECT count(*) FROM users;
count
-------
2
(1 row)
ysql_ebeans=# SELECT count(*) FROM products;
count
-------
2
(1 row)
ysql_ebeans=# SELECT count(*) FROM orders;
count
-------
2
(1 row)
ysql_ebeans=# SELECT * FROM orderline;
order_id | product_id | units
--------------------------------------+------------+-------
45659918-bbfd-4a75-a202-6feff13e186b | 1 | 2
f19b64ec-359a-47c2-9014-3c324510c52c | 1 | 2
f19b64ec-359a-47c2-9014-3c324510c52c | 2 | 4
(3 rows)
orderline
is a child table of the parent orders
table, and is connected using a foreign key constraint. The users
table is connected with orders
using a foreign key constraint so that no order can be placed with an invalid user, and that user has to be present in the users table.
Using the REST API
To use the REST API server to verify that the users, products, and orders were created in the ysql_ebeans
database, enter the following commands. The results are output in JSON format.
$ curl http://localhost:8080/users
{
"content": [
{
"userId": 1,
"firstName": "John",
"lastName": "Smith",
"email": "jsmith@example.com"
},
{
"userId": 101,
"firstName": "Tom",
"lastName": "Stewart",
"email": "tstewart@example.com"
}
],
...
}
$ curl http://localhost:8080/products
{
"content": [
{
"productId": 1,
"productName": "Notebook",
"description": "200 page notebook",
"price": 7.5
},
{
"productId": 2,
"productName": "Pencil",
"description": "Mechanical pencil",
"price": 2.5
}
],
...
}
$ curl http://localhost:8080/orders
{
"content": [
{
"orderTime": "2019-05-10T04:26:54.590+0000",
"orderId": "999ae272-f2f4-46a1-bede-5ab765bb27fe",
"orderOwner": {
"userId": 1,
"firstName": "John",
"lastName": "Smith",
"email": "jsmith@example.com"
},
"userId": null,
"orderTotal": 25.0,
"products": null
},
{
"orderTime": "2019-05-10T04:26:48.074+0000",
"orderId": "1598c8d4-1857-4725-a9ab-14deb089ab4e",
"orderOwner": {
"userId": 1,
"firstName": "John",
"lastName": "Smith",
"email": "jsmith@example.com"
},
"userId": null,
"orderTotal": 15.0,
"products": null
}
],
...
}
Explore the source
The application source is available in the orm-examples repository.