{"id":23902781,"url":"https://github.com/mtumilowicz/jpa-criteria-api","last_synced_at":"2025-10-15T11:08:02.727Z","repository":{"id":110878072,"uuid":"131856738","full_name":"mtumilowicz/jpa-criteria-api","owner":"mtumilowicz","description":"SQL, JPQL, HQL \u0026 JPA Criteria API training","archived":false,"fork":false,"pushed_at":"2018-08-19T20:28:31.000Z","size":138,"stargazers_count":3,"open_issues_count":0,"forks_count":2,"subscribers_count":0,"default_branch":"master","last_synced_at":"2025-09-20T10:44:17.741Z","etag":null,"topics":["criteria-api","hibernate","hql","jpa2","jpql","static-metamodels"],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mtumilowicz.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2018-05-02T13:44:15.000Z","updated_at":"2021-04-26T20:34:37.000Z","dependencies_parsed_at":"2023-07-21T14:17:19.639Z","dependency_job_id":null,"html_url":"https://github.com/mtumilowicz/jpa-criteria-api","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/mtumilowicz/jpa-criteria-api","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mtumilowicz%2Fjpa-criteria-api","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mtumilowicz%2Fjpa-criteria-api/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mtumilowicz%2Fjpa-criteria-api/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mtumilowicz%2Fjpa-criteria-api/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mtumilowicz","download_url":"https://codeload.github.com/mtumilowicz/jpa-criteria-api/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mtumilowicz%2Fjpa-criteria-api/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":279075630,"owners_count":26097952,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-15T02:00:07.814Z","response_time":56,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["criteria-api","hibernate","hql","jpa2","jpql","static-metamodels"],"created_at":"2025-01-04T22:50:34.917Z","updated_at":"2025-10-15T11:08:02.717Z","avatar_url":"https://github.com/mtumilowicz.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![Build Status](https://travis-ci.com/mtumilowicz/jpa-criteria-api.svg?branch=master)](https://travis-ci.com/mtumilowicz/jpa-criteria-api)\n\n# jpa-criteria-api\nThe main goal of this project is to explore basic query features of \n`JPA 2.1` specification:  \n* **JPQL**\n* **JPA Criteria API** (typesafe with auto-generated\nstatic metamodels)\n\nAs a `JPA` provider we choose `Hibernate` to test some of `HQL`.\n\n## project structure\n![](classes-diag.jpg)\n\n## technologies used\n* **Flyway** - constructs the database \u0026 provide datafeed in two migrations.\nEnsures data coherence by checking if schema in database is up to date (\nby validating additional database table concerning migrations: \n`flyway_schema_history`).  \n_Reference_: https://flywaydb.org/documentation/\n* **JPA 2.1**  \n_Reference_: [Pro JPA 2 2nd Edition](https://www.amazon.com/Pro-JPA-Experts-Voice-Java/dp/1430249269)  \n_Reference_: [JSR 338: JavaTM Persistence API, Version 2.1](http://download.oracle.com/otn-pub/jcp/persistence-2_1-fr-eval-spec/JavaPersistence.pdf)  \n* **Hibernate** - provider of `JPA 2.1` specification. We don't use\n`EclipseLink` despite the fact that it is `reference implementation` of\n`JPA 2.1` because apart from `JPQL` we want to explore `HQL` as a more\npowerful query language.  \n_Reference_: [Java Persistence with Hibernate Second Edition](https://www.amazon.com/exec/obidos/ASIN/1617290459)  \n_Reference_: [Hibernate Interview Questions and Answers](https://www.journaldev.com/3633/hibernate-interview-questions-and-answers)  \n* **Jupiter \u0026 AssertJ** - to test result sets (`AssertJ` has very \nconvinient methods to comparing lists regardless order).\n\n## project description  \n* The main idea is to explore `JPA Criteria API` by writing a querys in \n`JPQL` or `HQL`, then to try re-write them in `JPA Criteria API` \u0026 check \nresult-sets identity.  \n* Comparing equality of result sets with `JUnit` \u0026 `hamcrest`:\n    ```\n    import static org.hamcrest.Matchers.containsInAnyOrder;\n    ...\n    Assert.assertThat(entityManager.createQuery(cc_query)\n                .getResultList(),\n        containsInAnyOrder(jpql_query.getResultList().toArray()));\n    ```\n    but we decide to use `Jupiter` \u0026 `AssertJ` (more expressive):\n    ```\n    import static org.assertj.core.api.Assertions.assertThat;\n    ...\n    assertThat(entityManager.createQuery(cc_query).getResultList())\n        .containsExactlyInAnyOrderElementsOf(jpql_query.getResultList());\n    ```\n\n## project content\n`src/main/java`: entities, utility classes \u0026 `META-INF` folder with \n`persistence.xml`  \n`resources/db/migration`: `Flyway` migrations as `SQL` scripts  \n`test/java`: showcase of `JPQL`, `HQL` \u0026 `Criteria API` with tests  \n`target/generated-sources`: static metamodels of entities  \n\n## tests\n* We have to classes with nearly the same content: `Tests` and \n`TestsWithFullTypeSafe`. The only difference is that in the first class \nwe use strings to denote fields while in the letter we use static \nmetamodels.  \n* Example:  \n    * From `Tests`:  \n        ```\n        orderBy(cb.asc(cc_query_root.get(\"title\")));\n        ```\n    * From `TestsWithFullTypeSafe`:\n        ```\n        orderBy(cb.asc(cc_query_root.get(Book_.title)));\n        ```\n\n* All methods are quite simple \u0026 straightforward use of `Criteria API`.   \n    The most interesting are:  \n    * `getBookstoresWithMostExpensiveBook()` - we show how to use subqueries\n    * `getBookstoresThatHaveTitle()` - we show how to reference a `FROM` \n    expression of the parent query in the `FROM` clause of a subquery\n    * `getBookstoresThatHaveAtLeastOneBookWrittenBy()` - we show how to \n    reference a `JOIN` expression of the parent query in the `FROM` clause\n    of a subquery\n    * `countBooksByGenre()` - we show how to use `Tuple` with aliases\n    * `getBookstoresWithCountBooksAndPriceAverage()` - we show how to use \n    `multiselect` with dedicated class\n\n## static metamodels\nThey are auto-generated by `maven-compiler-plugin`.  \nAll you need to do is:  \n```\n\u003cplugin\u003e\n    \u003cgroupId\u003eorg.apache.maven.plugins\u003c/groupId\u003e\n    \u003cartifactId\u003emaven-compiler-plugin\u003c/artifactId\u003e\n    \u003cconfiguration\u003e\n        \u003csource\u003e1.8\u003c/source\u003e\n        \u003ctarget\u003e1.8\u003c/target\u003e\n        \u003ccompilerArguments\u003e\n            \u003cprocessor\u003eorg.hibernate.jpamodelgen.JPAMetaModelEntityProcessor\u003c/processor\u003e\n        \u003c/compilerArguments\u003e\n    \u003c/configuration\u003e\n\u003c/plugin\u003e\n```\n```\n\u003cdependency\u003e\n    \u003cgroupId\u003eorg.hibernate\u003c/groupId\u003e\n    \u003cartifactId\u003ehibernate-jpamodelgen\u003c/artifactId\u003e\n    \u003cversion\u003e5.2.17.Final\u003c/version\u003e\n    \u003cscope\u003eprovided\u003c/scope\u003e\n\u003c/dependency\u003e\n```\nMark `target/generated-sources` as a `Generated Sources Root`.  \nIn `IntelliJ` just left-click on `target/generated-sources` -\u003e \n`Mark Directory As` -\u003e `Generated Sources Root`.","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmtumilowicz%2Fjpa-criteria-api","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmtumilowicz%2Fjpa-criteria-api","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmtumilowicz%2Fjpa-criteria-api/lists"}