This project contains a simple Spring Web application. All endpoints fetch database entries from the Sakila test database, see Sakila database. The database is integrated using Hibernate with Panache and JPAStreamer, the latter both being Hibernate extensions that enrich the Hibernate API with more user-friendly query methods. Like Panache, JPAStreamer does not prohibit the use of HQL queries, it only extends the application with a type-safe query API.
To run the application, your environment must comply with the following prerequisites:
-
JDK 8 or later installed
-
Sakila film database running on port 3306, see Sakila database
JPAStreamer is an extension to any JPA provider that allows queries to be expressing as standard Java Streams. As it turns out, the Stream
interface introduced in Java 8, has a natural mapping to SQL that makes Stream database queries intuitive to most developers that are familiar with an imperative coding style.
Here is an example query that fetches 100 films that are longer than 2 hours, sorted alphabetically from the Sakila film database:
final JPAStreamer jpaStreamer = JPAStreamer.of("sakila");
Stream<Film> films = jpaStreamer.stream(Film.class)
.filter(Film$.length.greaterThan(120)) // WHERE
.sorted(Film$.title) // ORDER BY
.limit(100); // LIMIT
It is important to note that this is not the equivalent of streaming the whole database table, and then applying Java Stream operations on the result. Upon execution, JPAStreamer will optimize the pipeline by mapping each Stream operation to HQL and execute the resulting HQL query in the DB. In the above case, the pipeline results in the following HQL query:
select
film0_.film_id as film_id1_1_,
film0_.description as descript2_1_,
film0_.language_id as language3_1_,
film0_.last_update as last_upd4_1_,
film0_.length as length5_1_,
film0_.rating as rating6_1_,
film0_.rental_duration as rental_d7_1_,
film0_.rental_rate as rental_r8_1_,
film0_.replacement_cost as replacem9_1_,
film0_.title as title10_1_
from
film film0_
where
film0_.length>?
order by
film0_.title asc limit ?
The Film$
entity referenced in the filter
and sorted
operations is automatically generated by JPAStreamer from the standard JPA Entities Film
and Actor
to facilitate type-safety, and thereby unlock code-completion for developers. The generated sources are placed in the folder generated-sources/annotations/org/speedment/model
. In this demo application the folder contains the two generated entities from Film$
and Actor$
entities.
Note
|
The full documentation of JPAStreamer can be found here. |
To demonstrate how JPAStreamer operates, the Panache FilmRepository
contains paired implementations of a number of queries, where the first version is expressed using the Panache API and the other using the JPAStreamer API.
The JPAStreamer queries are executed via the endpoints at localhost:9001/jpastreamer/ and the Panache queries are executed from localhost:9001/panache/.
The demo makes use of the MySQL Sakila database. It can either be downloaded from Oracle as described here or used directly via a Sakila Docker instance by issuing the following commands:
$ docker pull restsql/mysql-sakila
$ docker run -d --publish 3306:3306 --name mysqld restsql/mysql-sakila
Note
|
This Docker image does not support ARM64 architecture, thus if you are running on e.g. an M1 Mac, you need to emulate an Intel image by adding the flag --platform linux/amd64 after docker run in the above command. This may not always work ideally, learn more about why at the Docker webpage.
|
Run the application in development mode with the following command:
./mvnw compile quarkus:dev
The application runs on port 9001:
http://localhost:9001
You can explore all available endpoints here:
http://localhost:9001/q/swagger-ui/#/
As this is an early preview of JPASteamer for Quarkus, JPAStreamer is not yet a formal Quarkus extension and therefore does not support native builds. Further the annotation processor is not yet compatible with Panache’s Active Record Pattern. We released this preview to gather early feedback before progressing with the development of the JPAStreamer Quarkus extension.