Skip to content

Latest commit

 

History

History

hibernate

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 
 
 

JPAstreamer Demo - Hibernate

This module contains examples showing how JPAstreamer can be used in conjunction with Hibernate. Although, please note that JPAstreamer can be used with any JPA provider.

Example Database

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 via IDE

Open the project as a Maven project in your IDE and execute any of the main-methods in one of the Demo-classes.

Run via Maven

To execute any of the demos, use the command mvn install exec:java@ followed by the demo name. For example:

mvn install exec:java@SimpleDemo1 

Demos

Below is a summary of the included examples.

SimpleDemo1

SimpleDemo1 shows how to create a stream of films of length between 100 and 120 minutes.

jpaStreamer.stream(Film.class)
    .filter(Film$.length.between(100, 120))
    .forEach(SimpleDemo1::printFilm);

Prints:

These are the films that are of length between 100 and 120 minutes:
   4 AFFAIR PREJUDICE          G     117
   9 ALABAMA DEVIL             PG-13 114
  19 AMADEUS HOLY              PG    113
  32 APOCALYPSE FLAMINGOS      R     119
  44 ATTACKS HATE              PG-13 113
  46 AUTUMN CROW               G     108
  48 BACKLASH UNDEFEATED       PG-13 118
  54 BANGER PINOCCHIO          R     113
  62 BED HIGHBALL              NC-17 106
  65 BEHAVIOR RUNAWAY          PG    100

Automatic Stream to JPA rendering:

select
        Film 
    from
        Film as Film 
    where
        Film.length between 100 and 120 

Automatic JPA to Hibernate SQL rendering:

select
    film0_.film_id as film_id1_1_,
    film0_.description as descript2_1_,
    film0_.language_id as languag11_1_,
    film0_.last_update as last_upd3_1_,
    film0_.length as length4_1_,
    film0_.rating as rating5_1_,
    film0_.rental_duration as rental_d6_1_,
    film0_.rental_rate as rental_r7_1_,
    film0_.replacement_cost as replacem8_1_,
    film0_.special_features as special_9_1_,
    film0_.title as title10_1_ 
from
    film film0_ 
where
    film0_.length between 100 and 120

CountDemo

CountDemo shows how to perform a count of all the elements that matches the query.

long count = jpaStreamer.stream(Film.class)
    .filter(Film$.length.between(100, 120))
    .count(); 

SimpleDemo1WithJoining

SimpleDemo1WithJoining as SimpleDemo1 but showing how to join in fields avoiding the "N + 1 select problem".

jpaStreamer.stream(of(Film.class).joining(Film$.actors).joining(Film$.language))
    .filter(Film$.length.between(100, 120))
    .forEach(SimpleDemo1::printFilm);

SimpleDemo2

SimpleDemo2 shows how to select five films with rating G, sort them by descending length and skip the first ten entries.

jpaStreamer.stream(Film.class)
    .filter(Film$.rating.equal("G"))
    .sorted(Film$.length.reversed().thenComparing(Film$.title.comparator()))
    .skip(10)
    .limit(5)
    .forEach(SimpleDemo2::printFilm);

Prints:

 126 CASUALTIES ENCINO         G     179
 692 POTLUCK MIXED             G     179
 897 TORQUE BOUND              G     179
 958 WARDROBE PHANTOM          G     178
 280 EMPIRE MALKOVICH          G     177

PaginationDemo

PaginationDemo demonstrates how to serve a page request from a GUI or a similar application.

return jpaStreamer.stream(Film.class)
    .sorted(comparator)
    .skip(page * PAGE_SIZE)
    .limit(PAGE_SIZE)
    .collect(Collectors.toList());

Prints:

CYCLONE FAMILY
DADDY PITTSBURGH
DAISY MENAGERIE
DALMATIONS SWEDEN
DANCES NONE
DANCING FEVER
DANGEROUS UPTOWN
...

PivotDemo

PivotDemo demonstrates how to make a pivot table containing all the actors and the number of films they have participated in for each film rating category (e.g. “PG-13”).

Map<Actor, Map<String, Long>> pivot = jpaStreamer.stream(Actor.class)
    .collect(
        groupingBy(Function.identity(),
                   Collectors.flatMapping(a -> a.getFilms().stream(),
                                          groupingBy(Film::getRating, counting())
                      )
                  )
            );

Prints:

SCARLETT BENING: {PG-13=7, R=5, NC-17=4, PG=5, G=5}
WOODY HOFFMAN: {PG-13=7, R=6, NC-17=5, PG=6, G=7}
ED MANSFIELD: {PG-13=4, R=8, NC-17=9, PG=5, G=6}
PARKER GOLDBERG: {PG-13=9, R=4, NC-17=5, G=2, PG=4}
...

PartitionDemo

PartitionDemo demonstrates how to partiton films into two buckets depending on film length:

Map<Boolean, List<Film>> map = jpaStreamer.stream(Film.class)
    .collect(
            Collectors.partitioningBy(Film$.length.greaterThan(120))
    );

Prints:

long is false has 543 films
long is  true has 457 films

OneToManyDemo

OneToManyDemo maps the languages to a list of all films that are spoken in that language.

Map<Language, Set<Film>> languageFilmMap = jpaStreamer.stream(Language.class)
    .limit(10)
    .collect(
        toMap(Function.identity(),Language::getFilms)
    );

Prints:

French: []
Mandarin: []
Italian: []
English: [INFORMER DOUBLE, CITIZEN SHREK, OCTOBER SUBMARINE, ANACONDA CONFESSIONS, ...]
German: []
...

ManyToOneDemo

ManyToOneDemo maps every film with rating PG-13 to its spoken language.

Map<Film, Language> languageMap = jpaStreamer.stream(Film.class)
     .filter(Film$.rating.equal("PG-13"))
     .collect(
         Collectors.toMap(Function.identity(), Film::getLanguage)
     );

Prints:

EXPECATIONS NATURAL: English
SINNERS ATLANTIS: English
TRIP NEWTON: English
WRONG BEHAVIOR: English
STRICTLY SCARFACE: English
MICROCOSMOS PARADISE: English
...

ManyToManyDemo

ManyToManyDemo demonstrates how to create a filmography that maps every actor to a list of films that they have starred in.

Map<Actor, List<Film>> filmography = jpaStreamer.stream(Actor.class)
     .collect(
         Collectors.toMap(Function.identity(), Actor::getFilms)
     );

Prints:

MARY TANDY: [BARBARELLA STREETCAR, CHILL LUCK, DANGEROUS UPTOWN, ...]
KEVIN BLOOM: [AMERICAN CIRCUS, BOOGIE AMELIE, CITIZEN SHREK, ...]
DUSTIN TAUTOU: [AFRICAN EGG, AUTUMN CROW, BANGER PINOCCHIO, ...]
...

TransactionDemo

TransactionDemo demonstrates a JPA transaction that updates the rental rate of a selection of films.

try {
    em.getTransaction().begin();

    jpaStreamer.stream(Film.class)
        .filter(Film$.rating.equal("R"))
        .forEach(f -> {
                f.setRentalRate(f.getRentalRate() + 1);
                em.merge(f);
            }
        );

    em.getTransaction().commit();
} catch(Exception e) {
    e.printStackTrace();
    em.getTransaction().rollback();
}

Prints:

Rental rates before raise:
The rental rate for AIRPORT POLLOCK is $4.990000.
The rental rate for ALONE TRIP is $0.990000.
The rental rate for AMELIE HELLFIGHTERS is $4.990000.
The rental rate for AMERICAN CIRCUS is $4.990000.
The rental rate for ANACONDA CONFESSIONS is $0.990000.
...
Rental rates after the raise:
The rental rate for AIRPORT POLLOCK is $5.990000.
The rental rate for ALONE TRIP is $1.990000.
The rental rate for AMELIE HELLFIGHTERS is $5.990000.
The rental rate for AMERICAN CIRCUS is $5.990000.
The rental rate for ANACONDA CONFESSIONS is $1.990000.
...

Configuration

This repository is configured to work without modification if you use the Docker instance. However, we provide you with details about the Maven and Hibernate configuration below if you wish to set up your own tests.

Maven

The following main dependencies are needed for the project:

    <dependencies>

        <dependency>
            <groupId>com.speedment.jpastreamer</groupId>
            <artifactId>core</artifactId>
            <version>${jpa-streamer-version}</version>
        </dependency>

        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-core</artifactId>
            <version>5.4.17.Final</version>
        </dependency>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.21</version>
        </dependency>

    </dependencies>

Here is the complete pom.xml file.

JPA Configuration

The demos are using Hibernate as the JPA provider. The resources/META-INF/persistence.xml file looks like this:

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.2"
             xmlns="http://xmlns.jcp.org/xml/ns/persistence"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence
     http://xmlns.jcp.org/xml/ns/persistence/persistence_2_2.xsd">

    <persistence-unit name="sakila" transaction-type="RESOURCE_LOCAL">
        <description>Test</description>
        <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
        <properties>
            <!-- Configuring The Database Connection Details -->
            <property name="javax.persistence.jdbc.driver" value="com.mysql.cj.jdbc.Driver" />
            <property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/sakila" />
            <property name="javax.persistence.jdbc.user" value="root" />
            <property name="javax.persistence.jdbc.password" value="sakila" />
<!--        <property name="hibernate.show_sql" value="true"/> -->
            <property name="hibernate.format_sql" value="true"/>
            <property name="hibernate.use_sql_comments" value="true"/>
<!--        <property name="hibernate.dialect" value="org.hibernate.dialect.MySQL8Dialect"/>-->

        </properties>
    </persistence-unit>
</persistence>

As can be seen, the persistence name is "sakila" and this name is consequently used by JPAstreamer in the demos above.

Resources