The main goal of this project is to explore basic query features of
JPA 2.1 specification:
- JPQL
- JPA Criteria API (typesafe with auto-generated static metamodels)
As a JPA provider we choose Hibernate to test some of HQL.
- Flyway - constructs the database & provide datafeed in two migrations.
Ensures data coherence by checking if schema in database is up to date (
by validating additional database table concerning migrations:
flyway_schema_history).
Reference: https://flywaydb.org/documentation/ - JPA 2.1
Reference: Pro JPA 2 2nd Edition
Reference: JSR 338: JavaTM Persistence API, Version 2.1 - Hibernate - provider of
JPA 2.1specification. We don't useEclipseLinkdespite the fact that it isreference implementationofJPA 2.1because apart fromJPQLwe want to exploreHQLas a more powerful query language.
Reference: Java Persistence with Hibernate Second Edition
Reference: Hibernate Interview Questions and Answers - Jupiter & AssertJ - to test result sets (
AssertJhas very convinient methods to comparing lists regardless order).
- The main idea is to explore
JPA Criteria APIby writing a querys inJPQLorHQL, then to try re-write them inJPA Criteria API& check result-sets identity. - Comparing equality of result sets with
JUnit&hamcrest:but we decide to useimport static org.hamcrest.Matchers.containsInAnyOrder; ... Assert.assertThat(entityManager.createQuery(cc_query) .getResultList(), containsInAnyOrder(jpql_query.getResultList().toArray()));Jupiter&AssertJ(more expressive):import static org.assertj.core.api.Assertions.assertThat; ... assertThat(entityManager.createQuery(cc_query).getResultList()) .containsExactlyInAnyOrderElementsOf(jpql_query.getResultList());
src/main/java: entities, utility classes & META-INF folder with
persistence.xml
resources/db/migration: Flyway migrations as SQL scripts
test/java: showcase of JPQL, HQL & Criteria API with tests
target/generated-sources: static metamodels of entities
-
We have to classes with nearly the same content:
TestsandTestsWithFullTypeSafe. The only difference is that in the first class we use strings to denote fields while in the letter we use static metamodels. -
Example:
- From
Tests:orderBy(cb.asc(cc_query_root.get("title"))); - From
TestsWithFullTypeSafe:orderBy(cb.asc(cc_query_root.get(Book_.title)));
- From
-
All methods are quite simple & straightforward use of
Criteria API.
The most interesting are:getBookstoresWithMostExpensiveBook()- we show how to use subqueriesgetBookstoresThatHaveTitle()- we show how to reference aFROMexpression of the parent query in theFROMclause of a subquerygetBookstoresThatHaveAtLeastOneBookWrittenBy()- we show how to reference aJOINexpression of the parent query in theFROMclause of a subquerycountBooksByGenre()- we show how to useTuplewith aliasesgetBookstoresWithCountBooksAndPriceAverage()- we show how to usemultiselectwith dedicated class
They are auto-generated by maven-compiler-plugin.
All you need to do is:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
<compilerArguments>
<processor>org.hibernate.jpamodelgen.JPAMetaModelEntityProcessor</processor>
</compilerArguments>
</configuration>
</plugin>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-jpamodelgen</artifactId>
<version>5.2.17.Final</version>
<scope>provided</scope>
</dependency>
Mark target/generated-sources as a Generated Sources Root.
In IntelliJ just left-click on target/generated-sources ->
Mark Directory As -> Generated Sources Root.
